19、企业应用的维护与管理:守护进程、服务及监控

企业应用的维护与管理:守护进程、服务及监控

1. 企业软件开发的特点

企业环境下的软件开发与其他场景有所不同。通常,企业开发者以大型团队形式工作,经常需要复用专有库和应用程序,并且要与运维和 QA 部门紧密合作。与桌面应用相比,许多企业应用没有用户界面,而是作为守护进程或服务在后台运行。实现这些后台进程可能具有一定难度,因此需要借助工具实现自动化。

2. 将代码转换为守护进程和服务

在企业环境中,经常需要创建守护进程,即无控制终端在后台运行的进程,如 HTTP 服务器。手动将进程转换为守护进程较为复杂,可借助库实现自动化。

2.1 不同平台的准备工作
  • Unix 类操作系统 :安装 daemons gem。
$ gem install daemons
  • Windows 平台 :安装 win32-service gem。
$ gem install win32-service
2.2 示例测试应用

以下是一个观察目录中是否有新文件的服务器,它等待以 XML 编码的新订单。输入文件名必须以 order 开头,扩展名为 .xml

# order_import.rb
require 'logger'

working_dir = ARGV[0] || '/tmp/orders'
interval = (ARGV[1] || 10).to_i
logger = Logger.new File.join(working_dir, 'order_import.log')
logger.info 'Started order import...'

loop do
  orders = Dir["#{working_dir}/order*.xml"]
  orders.each do |filename|
    logger.info "Processing #{filename}."
    # Do something with order file...
    File.delete(filename)
  end
  sleep interval
end

该程序开始时定义了几个变量: working_dir 指向期望新订单到达的目录, interval 定义检查工作目录中是否有新文件的频率(默认 10 秒), logger 用于将程序活动记录到文件中。然后进入一个无限循环,读取工作目录中的所有新订单输入文件,处理后删除文件,最后程序休眠指定的秒数。

2.3 在 Unix 类系统中转换为守护进程

使用 Daemons 库将上述程序转换为守护进程,只需在程序开头添加以下代码:

# instant_daemon.rb
require 'daemons'
Daemons.daemonize :backtrace => true

daemonize() 方法接受一个选项哈希,支持两个可选选项。 backtrace 选项可方便调试守护进程,当设置该选项时,守护进程会将最后异常的回溯信息写入 pid/[app_name].log 文件。如果 ontop 设置为 true ,程序不会作为守护进程运行,这在调试时很有用。

创建守护进程后,需要工具来停止和重启它。 Daemons 库支持通过进程 ID(PID)文件控制守护进程。创建以下控制脚本:

# order_import_control.rb
require 'daemons'
Daemons.run(File.join(File.dirname(__FILE__), 'order_import.rb'))

可以使用以下命令控制订单导入进程:

$# Start the process in the background:
$ ruby order_import_control.rb start
$# Restart the process:
$ ruby order_import_control.rb restart
$# Stop the process:
$ ruby order_import_control.rb stop
$# Start the process in the foreground:
$ ruby order_import_control.rb run

在 Ruby 1.9 中, Process 类有一个新的类方法 daemon(stay_in_dir=false,keep_stdio_open=false) ,可将当前进程转换为守护进程并放入后台。但该方法并非在所有平台都可用,仅在支持的平台且不打算迁移应用时使用。

2.4 在 Windows 平台实现服务

在 Windows 平台,使用 win32-service 库将订单导入进程实现为服务。以下是实现代码:

# order_import.rb
require 'logger'
require 'win32/daemon'
include Win32

class OrderImportService < Daemon
  def initialize(opts = {})
    super()
    @opts = opts
  end

  def service_init
    @interval = @opts[:interval] || 10
    @working_dir = @opts[:working_dir] || 'c:/orders'
    @logger = Logger.new(@opts[:logfile] || 'c:/order_import.log')
    @logger.info 'Starting order import...'
  end

  def service_main
    @logger.info 'Order import has been started.'
    while running?
      orders = Dir["#{@working_dir}/order*.xml"]
      orders.each do |filename|
        @logger.info "Processing #{filename}."
        # Do something with order file...
        File.delete(filename)
      end
      sleep(@interval)
    end
    @logger.info 'Order import has been stopped.'
  end
end

if __FILE__ == $0
  order_import_service = OrderImportService.new
  order_import_service.mainloop
end

该服务定义了一个类 OrderImportService ,继承自 Daemon service_init() 方法在服务启动时调用,用于初始化数据和文件; service_main() 方法实现服务的主要逻辑,使用 running? 方法检查服务是否仍在运行。

在启动服务之前,需要安装服务。使用 Service 类编写安装方法:

# install_service.rb
require 'win32/service'
include Win32

def install_service(name, display_name, executable)
  Service.create(
    name,
    nil,
    :display_name => display_name,
    :binary_path_name => 'ruby ' + File.expand_path(executable)
  )
  puts "Service #{name} has been installed."
end

install_service(
  'order_import',
  'Order Import',
  'order_import.rb'
)

安装服务后,可以使用 Windows 服务管理控制台管理服务。以下是一个管理服务的示例程序:

# service_management.rb
require 'win32/service'
include Win32

def wait_for_state(state)
  print "Waiting for state '#{state}'"
  i = 0
  while Service.status('order_import').current_state != state
    i += 1
    print '.' if i % 1000 == 0
  end
  puts
end

puts "Display name: #{Service.get_display_name('order_import')}"
Service.configure(
  'order_import',
  nil,
  :display_name => 'Order Import 2008'
)
Service.start('order_import')
wait_for_state('running')
puts 'Service has been started.'
Service.pause('order_import')
wait_for_state('paused')
puts 'Service has been paused.'
Service.resume('order_import')
puts 'Service has been resumed.'
wait_for_state('running')
Service.stop('order_import')
wait_for_state('stopped')
puts 'Service has been stopped.'
Service.delete('order_import')
puts 'Service has been uninstalled.'
3. 使用 Monit 监控应用程序

编写的许多 Ruby 程序已成为公司基础设施的重要组成部分,但有时会崩溃,需要自动重启。 monit 是一个监控工具,可以完成这项任务。

3.1 安装 Monit
$ wget http://www.tildeslash.com/monit/dist/monit-4.10.1.tar.gz
$ tar xzvf monit-4.10.1.tar.gz
$ cd monit-4.10.1
$ ./configure && make && sudo make install
3.2 Monit 配置文件

以下是一个监控系统和订单导入守护进程的配置文件:

# monitrc.conf
set daemon 60
set logfile '/tmp/monitoring.log'
set mailserver smtp.example.com username "sysadm" password "t0p$ecret"
set alert admin@example.com { nonexist, timeout } with mail-format {
  from: monit@example.com
}
set alert boss@example.com only on { timeout }
set httpd port 2812 and
use address localhost
allow localhost
allow admin:monit

# Check the system's status:
check system localhost
if loadavg(1min) > 4 then alert
if loadavg(5min) > 2 then alert
if memory usage > 75% then alert
if cpu usage(user) > 70% then alert
if cpu usage(system) > 30% then alert
if cpu usage(wait) > 20% then alert

# Check status of order import daemon:
check process order_import with pidfile /tmp/order_import.rb.pid
start program = "/tmp/order_import_control.rb start"
stop program = "/tmp/order_import_control.rb stop"
if cpu > 60% for 2 cycles then alert
if cpu > 80% for 5 cycles then restart
if totalmem > 100.0 MB for 5 cycles then restart
if loadavg(5min) greater than 8 for 6 cycles then stop
if 3 restarts within 5 cycles then timeout
group server

该配置文件逐行解析如下:
- 第 1 行:设置 monit 作为守护进程启动,每 60 秒检查一次所有受监控的进程。
- 第 2 行:配置 monit 用于记录重要事件的日志文件。
- 第 3 行:配置用于发送邮件的邮件服务器。
- 第 4 - 7 行:定义邮件通知的接收者和条件。
- 第 8 - 11 行:配置 monit 的 HTTP 服务器,监听端口 2812,只允许本地访问,使用用户名和密码进行身份验证。
- 第 14 - 20 行:检查系统状态,如负载平均值、内存使用率、CPU 使用率等,超过阈值则发出警报。
- 第 23 - 30 行:检查订单导入守护进程的状态,指定启动和停止程序的命令,根据 CPU、内存、负载平均值等条件进行警报、重启或停止操作。
- 第 31 行:将订单导入进程放入 “server” 组。

3.3 使用配置文件监控守护进程

使用以下命令启动 monit 进程:

$ monit -c monitrc.conf

启动后, monit 会立即注意到订单导入进程未运行并尝试重启它,同时发送邮件通知。可以使用以下命令启动、停止或重启所有进程或进程组:

$ monit -c monitrc.conf start all
$ monit -c monitrc.conf -g server restart all

如果不再需要 monit ,可以使用以下命令终止它:

$ monit -c monitrc.conf quit
3.4 查看监控状态

可以通过 monit 的日志文件查看监控状态,也可以通过浏览器访问 http://localhost:2812 查看进程的详细状态。

4. 总结

通过上述方法,可以将 Ruby 应用程序转换为守护进程或服务,并使用 monit 工具监控应用程序的运行状态,确保其稳定运行。不同平台的实现方式有所不同,但都有相应的工具和方法来完成这些任务。

以下是将代码转换为守护进程和服务的流程图:

graph TD;
    A[选择平台] --> B{Unix类系统};
    A --> C{Windows平台};
    B --> D[安装daemons gem];
    C --> E[安装win32-service gem];
    D --> F[编写测试应用];
    E --> F;
    F --> G[使用Daemons库转换为守护进程(Unix)];
    F --> H[定义服务类(Windows)];
    G --> I[创建控制脚本];
    H --> J[安装服务];
    I --> K[控制守护进程];
    J --> L[管理服务];

以下是使用 Monit 监控应用程序的步骤表格:
| 步骤 | 操作 |
| ---- | ---- |
| 1 | 安装 Monit |
| 2 | 编写 Monit 配置文件 |
| 3 | 使用配置文件启动 Monit |
| 4 | 查看监控状态(日志文件或 Web 界面) |

企业应用的维护与管理:守护进程、服务及监控

5. 企业应用标准的封装与复用

许多公司在软件开发过程中有各种各样的标准,例如开发者需要按照特定方案命名对象,Web 应用需要遵循特定的样式指南等。为了简化开发工作,将这些标准封装到可复用的组件中是一个不错的选择。

5.1 创建 Rails 插件

创建自己的 Rails 插件可以帮助我们封装通用的功能和标准。虽然文档中没有详细给出创建 Rails 插件的具体代码示例,但我们知道通过创建插件,可以将一些常用的功能模块化,方便在不同的项目中复用。

5.2 创建自定义生成器

避免代码重复的另一个有效方法是创建自定义生成器。同样,文档未给出具体代码,但创建自定义生成器可以根据项目的标准和需求,自动生成符合规范的代码结构,提高开发效率。

6. 不同平台实现守护进程和服务的对比
平台 实现方式 工具 特点
Unix 类系统 将进程转换为守护进程 daemons gem 实现相对简单,可通过控制脚本方便地启动、停止和重启守护进程
Windows 平台 将程序实现为服务 win32-service gem 需要定义服务类,通过 Windows 服务管理控制台进行管理

以下是不同平台实现守护进程和服务的对比流程图:

graph TD;
    A[开发需求] --> B{选择平台};
    B --> C{Unix类系统};
    B --> D{Windows平台};
    C --> E[使用daemons gem];
    D --> F[使用win32-service gem];
    E --> G[守护进程控制灵活];
    F --> H[服务管理依赖控制台];
7. 监控工具的重要性及选择

在企业应用中,监控工具至关重要。像 monit 这样的工具可以实时监控系统和应用程序的状态,当出现异常时及时发出警报并采取相应的措施,如重启或停止进程。选择监控工具时,需要考虑以下因素:
- 功能全面性 :能否监控系统的各种指标,如 CPU 使用率、内存使用率、负载平均值等。
- 配置灵活性 :是否具有强大的配置语言,能够根据不同的需求进行定制化配置。
- 平台兼容性 :是否支持目标平台的监控。

8. 实际应用中的注意事项

在实际应用中,将代码转换为守护进程和服务以及使用监控工具时,还需要注意以下几点:
- 日志记录 :无论是守护进程、服务还是监控工具,都要重视日志记录。日志可以帮助我们排查问题,了解程序的运行状态。
- 路径问题 :在守护进程中,要确保使用的文件路径是绝对路径,因为守护进程通常会将当前工作目录更改为根目录。
- 调试技巧 :在调试守护进程和服务时,可以利用工具提供的调试选项,如 Daemons 库的 ontop 选项,方便定位问题。

9. 未来展望

随着企业应用的不断发展,对应用的维护和管理要求也会越来越高。未来可能会出现更多功能强大、使用便捷的工具和技术,帮助我们更高效地完成应用的维护和管理工作。例如,可能会有更智能的监控工具,能够自动分析系统状态并预测潜在的问题;也可能会有更简单的跨平台实现守护进程和服务的方法,减少不同平台之间的差异带来的开发成本。

总之,掌握将代码转换为守护进程和服务的方法,以及使用监控工具对应用进行实时监控,是企业应用维护和管理的重要技能。通过合理运用这些技术和工具,可以提高应用的稳定性和可靠性,为企业的发展提供有力支持。

以下是企业应用维护与管理的整体流程总结列表:
1. 根据公司标准封装可复用组件(创建 Rails 插件和自定义生成器)。
2. 选择合适的平台,根据平台特点将代码转换为守护进程或服务。
- Unix 类系统:安装 daemons gem,编写测试应用,使用 Daemons 库转换为守护进程,创建控制脚本。
- Windows 平台:安装 win32-service gem,定义服务类,安装服务。
3. 使用监控工具(如 monit )对应用进行监控。
- 安装监控工具。
- 编写监控配置文件。
- 启动监控工具并查看监控状态。
4. 在实际应用中注意日志记录、路径问题和调试技巧。
5. 关注未来技术发展,不断提升应用维护和管理的能力。

带开环升压转换器和逆变器的太阳能光伏系统 太阳能光伏系统驱动开环升压转换器和SPWM逆变器提供波形稳定、设计简单的交流电的模型 Simulink模型展示了一个完整的基于太阳能光伏的直流到交流电力转换系统,该系统由简单、透明、易于理解的模块构建而成。该系统从配置为提供真实直流输出电压的光伏阵列开始,然后由开环DC-DC升压转换器进行处理。升压转换器将光伏电压提高到适合为单相全桥逆变器供电的稳定直流链路电平。 逆变器使用正弦PWM(SPWM)开关来产生干净的交流输出波形,使该模型成为研究直流-交流转换基本操作的理想选择。该设计避免了闭环和MPPT的复杂性,使用户能够专注于光伏接口、升压转换和逆变器开关的核心概念。 此模型包含的主要功能: •太阳能光伏阵列在标准条件下产生~200V电压 •具有固定占空比操作的开环升压转换器 •直流链路电容器,用于平滑和稳定转换器输出 •单相全桥SPWM逆变器 •交流负载,用于观察实际输出行为 •显示光伏电压、升压输出、直流链路电压、逆变器交流波形和负载电流的组织良好的范围 •完全可编辑的结构,适合分析、实验和扩展 该模型旨在为太阳能直流-交流转换提供一个干净高效的仿真框架。布局简单明了,允许用户快速了解信号流,检查各个阶段,并根据需要修改参数。 系统架构有意保持模块化,因此可以轻松扩展,例如通过添加MPPT、动态负载行为、闭环升压控制或并网逆变器概念。该模型为进一步开发或整合到更大的可再生能源模拟中奠定了坚实的基础。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值