- 浏览: 217324 次
- 性别:
- 来自: 北京
-
文章分类
最新评论
-
q10000000:
你好 适用madMadia点击上传到服务器 没有反应啊LZ
在项目中整合FCKeditor文本编辑器 -
liweixxxx1990:
spring本版是3.0的(和版本也有关系吗?) 配置用到了s ...
struts2+spring发送mail -
floger:
liweixxxx1990 写道我照着你这个写的出现了下面的错 ...
struts2+spring发送mail -
liweixxxx1990:
我照着你这个写的出现了下面的错误,怎么解决啊??:Messag ...
struts2+spring发送mail -
jueyue:
不错,把问题解决了
Myeclipse下java.lang.OutOfMemoryError: Java heap space的解决
https://docs.google.com/document/pub?id=1FCcJNu5DrNzRKvQOZ7bdnCMT1R7gyDthHMOqd1gYmBs
浅析Ruby on Rails部署方案 ShiningRay
浅析Ruby on Rails部署方案
目录
前言
简介
前端的选择
后端的选择
性能测试
后端的问题
前端的问题
前后端搭配的测试
测试结果
分析和小结
延伸
其它问题
总结
前言
2006初,我接到了公司分配的一个遗留项目,让我负责一个基于C/S的系统的服务器端。其实是系统是基于HTTP协议的,因为负责客户端的同事对于服务器端编程不甚了解,虽然使用PHP对熟悉C++的他来说是驾轻就熟,但是在进一步实现更多的功能和更高的性能上就捉襟见肘了。项目是在非常突然的情况下交给我的,因为该同事在客户端上有更多的事情要做。我在分析了他的数据库结构和PHP源代码之后,决定按照与客户端的通讯协议重写他的服务器端。为了能应付老板苛刻的时间限制,我打算使用正在学习的Ruby on Rails。后来,项目在功能上非常顺利地交付了。
两年过去了,随着客户端数量的不断增加、客户端功能的增加、与服务器端交互数据的增加、老板对功能的要求不断增加,我在这个项目上走了不少弯路,尤其是在部署——或者说是架构——方面。
我遇到的最大的问题就在于并发链接数上。服务器与客户端的每次交互的数据量并不大,但内容无法缓存。起初用的是Nginx/Apache+Mongrel的部署方式,但当遇到大量并发请求时,常常会遇到Mongrel进程死掉的情况。而客户端的用户在无法登录客户端的时候,经常会反复尝试,加重了服务器的负担、导致最后所有的Mongrel进程都挂掉。
最后,经过不懈努力,在现有的3台低端服务器上,可以满足每天500万次的请求。在这里,我将我的一些心得和研究成果总结出来,与大家分享。
简介
Ruby on Rails的部署方案基本上都是由两层结构组成,前端做请求的分发,后端以多个Ruby进程接受并处理请求,主要的差别便是其中的通讯协议,比如使用FastCGI 或者是HTTP。这里讨论的局限于一台服务器,所以我不称之为架构方案,而仅仅是部署配置方案。
前端的选择
前端也有很多种不同的选择,我们来看一下开源领域主流的选择:
Apache功能十分强大,稳定性也十分好,是全球市场占有率最高的Web服务器。与它搭配的Rails部署方案也有很多,如:
- Apache+mod_ruby:类似于mod_php、mod_python,将Ruby解释器作为一个模块加载到Apache中。(mod_ruby以及停止更新,所以并不流行)
- Apache+mod_fastcgi或Apache+mod_fcgid,通过FastCGI协议与Rails进程通讯。(mod_fastcgi由于设计有缺陷因此仅推荐使用mod_fcgid)
- Apache2.2 + mod_proxy_balancer:使用反向代理负载均衡器,通过HTTP与后端的Ruby Web服务器通讯,如Mongrel/Thin/Ebb等。
- Apache2 + Passenger (mod_rails) :新兴的模块方式,部署方式十分简单,大致的方式和FastCGI差不多,只不过与后台进程间的通讯协议使用了它自己的协议。
Apache的一大问题就是Apache的性能和一些轻量级新秀Web服务器相比差很多,原因在于Apache到目前为止仅有prefork(进程)模式和worker(线程)模式的MPM是稳定的,这两种工作方式每服务一个链接,就需要创建一个进程或线程,而新兴的轻量级Web服务器,则都很好地利用内核的事件机制提高性能,极大地减少了线程或进程数量,而Apache的event(事件)模式的MPM依然在开发中。例如,Apache的请求处理速度、并发处理能力都比Lighttpd慢3-5倍,内存消耗和CPU消耗也高出很多。另一个问题是,mod_proxy_balancer虽然功能强大,但分发性能不高,比HAproxy或Nginx差很多。
基于这些问题,所以Apache+FastCGI/mod_proxy_balancer的部署方案并不流行,然而新兴的Passenger由于部署方式出奇简单,使得Apache可能会重新在Rails部署上再次占据一席之地。
轻量级高性能Web服务器,服务静态文件的性能非常高。目前的稳定版本Lighttpd1.4中的反向代理模块有所缺陷,此模块会在1.5中全部重写并提供更好的负载均衡算法,可以对基于FastCGI、HTTP、AJP、SCGI的后端进行请求分发。Lighttpd+FastCGI是目前非常流行的一种部署方式,国内著名的JavaEye便采用的这种方式,JavaEye 负责人之一Robbin对Lighttpd+FastCGI的方式推崇备至。
Nginx也是一个轻量级高性能的Web服务器/反向代理负载均衡器。Nginx也支持FastCGI,但不像Lighttpd 1.5支持对FastCGI后端的负载均衡调度。Nginx+Mongrel的方式受到很多人推荐。
HAproxy是一个纯粹的反向代理均衡器,非常小巧,基于事件机制。它不仅可以做HTTP反向代理,还可以作TCP的转发,所以同样可以对FastCGI做负载均衡。在做HTTP反向代的同时可以对请求作一些修改控制。在ThoughtWorks推出的Rubyworks这个Rails应用套件中用到了它,原因是它能很方便地限制到后端服务器的链接数量。但HAproxy不是Web服务器,它不能处理静态文件。
Swiftiply是一个负载均衡反向代理,但它与后端服务器的通讯方式很特殊——它开放一个端口让后端服务器主动链接到Swiftiply,这样可以与后端服务器建立一个持久链接,而且无须重启就可以非常容易地增加新的后端。Swiftiply使用了Ruby的EventMachine 实现了实践驱动机制。支持它的协议的后端有Swiftiplied Mongrel和Thin。
后端的选择
后端Rails的运行方式可以通过FastCGI或者是Ruby应用服务器的方式,CGI和mod_ruby已经不推荐。可以选的Ruby服务器有有:
WEBrick是Ruby标准库中自带的默认HTTP服务器,完全使用Ruby写成,性能较差。利用了Ruby的线程来服务并发的链接。有人写了利用事件机制来提高性能的补丁,由于应用少,不在讨论范围。
目前最为成熟Ruby应用服务器。使用了C++写的HTTP头解析器,所以具有较好的性能,它同样利用了Ruby的线程机制来服务并发的链接。Mongrel的优点是稳定,兼容性好,很多平台上都可以使用,包括JRuby。Swiftiply小组还写了一个利用EventMachine的Mongrel修改版,称之为Evented Mongrel,使用单线程、事件驱动方式。
利用事件驱动机制的Ruby应用服务器,并借用了Mongrel的HTTP头解析器,事件机制的部分同样是利用了EventMachine。相比Mongrel来说,稳定性和兼容性略差。例如,我在CentOS 3.2的平台上编译后启动便崩溃。
又一个高性能的Ruby应用服务器,有多种工作模式,可以使用事件驱动机制,也可以使用线程模式。据说线程模式服务Merb(另一个Ruby的Web应用框架)可以达到更好的性能。和Thin一样,由于刚出现不久,还不是非常稳定。它要求Glibc 2以上版本,所以老版本的Linux无法使用,另外我在自己的Ubuntu 8.04上编译的版本在运行中无法正常接受链接,所以在本文中没有涉及到Ebb的测试。
性能测试
为了了解各种前、后端程序搭配的方式各自的性能如何,必须做大量的测试。下面我将我为公司做的这个项目所进行的一系列测试的结果展示出来,并做简单的分析。
我利用了Apache Benchmark(ab),对服务器端压力最大的身份验证部分进行压力测试。
注意:这些测试都相对比较简单和宽松,很多因素、细节没有考虑进去,只是作为一个参考。而且,对于不同的Rails应用、应用中的不同部分,都应该做独立的测试,来找到最合适的部署方法。
后端的测试 首先,我们先测试我们所使用的后端在同一台机器上的性能,由于前端通常通过内部环路或UNIX套接字与后端通讯,所以我没有从另外一台机器上进行测试。由于ab不能直接测试FastCGI,为了能了解FastCGI的性能,我通过Nginx来与FastCGI通讯,分别测试TCP和Unix套接字的性能,将这个测试结果做个参考。
测试机器为ThinkPad T43,Intel Pentium M 1.86G,1.5G RAM,系统为Ubuntu 8.04,内核版本为2.6.24-16。
被测试的对象的版本为:
- Mongrel 1.1.3,以及Evented Mongrel
- Thin 0.8.1(EventMachine 0.10.0)
- fcgi 0.8.7(Nginx 0.6.29)
以上全部使用默认配置。测试方法是从1开始,以10为步长,到500的数值,作为并发链接数,每次测试1000个请求,得到的ab的报告中取每秒的请求数作为测试的结果。
由于Ebb没有能在我的系统上成功运行起来,所以尚未得到它的数据。其中Thin还支持KeepAlive,所以单独进行了测试,由于这个服务器的应用主要是动态内容,所以后面的测试都不测KeepAlive。
测试结果如下,左边的图是点和线,为了不让画面太乱,能清晰地了解的性能情况,我取了B样条,如右图:
我们从图上,在结合一些现有的知识,可以印证一些概念:
测试的前半部分FastCGI比HTTP快的原因是:
- 由于FastCGI是二进制协议,避免了HTTP协议复杂的格式解析、生成的消耗——这部分内容通常由更高效的前端服务器来完成。
- FastCGI与前端服务器之间建立的是持久链接,避免了大量的打开关闭套接字的操作。
我们也看到了起初支持KeepAlive的Thin处理请求的速度也很快,同样应该是得益于持久链接,减少了打开关闭套接字的操作而造成的。
两个FastCGI的测试,虽然TCP套接字的额外开销要比UNIX套接字高一点,但基本是接近的,因为这两者性能的差异与Rails应用本身的处理速度相比是很微小的。所以FastCGI无论是走TCP还是走Unix套接字性能都是接近的。
然而,当FastCGI接受的并发链接数量不断上升时,请求的处理速度不断降低,这是因为FastCGI的处理请求方式是阻塞的,每次只处理一个请求(可以从fcgi包中的代码中看出来),随着并发链接数量上升,维持链接的开销越来越大。同样的情况也发生在使用了KeepAlive的Thin中。
测试中,Mongrel的响应速度非常稳定。虽然性能在前250并发量的测试中占下风,但是随着并发链接数的上升,它利用线程的好处逐渐显现出来。Thin虽然使用了单线程,由于是基于事件驱动,与Mongrel性能相差不多,但稳定性则低了。
Evented Mongrel的性能令人印象深刻,在后半部的测试中占据了上风。同样使用了EventMachine的Thin,性能却不如它,我觉得可能在于:一、Mongrel不支持KeepAlive,Thin支持,所以需要作额外的考虑;二、可能是Mongrel的HTTP头解析器性能更好。关于第一个因素,我将最大持久链接数设为了0,最后的测试结果是比Mongrel还要低。至于进一步研究为什么,就不在本文讨论了。
后端的问题
在前面的测试报告中,我们似乎看不出什么问题,好像即使处理速度不够,多开几个进程就可以了。这是因为测试是在比较理想的环境下进行的,而实际的生产环境情况要复杂得多。虽然Mongrel在此次测试的结果中显示了很好的稳定性,但是这并不能表示Mongrel就可以在生产环境中同样保持很好的稳定性。
原因在于Ruby的线程机制。但首先这里要强调的是,虽然Ruby的虚拟机有缺陷,线程是伪线程,线程性能较差,但这并不妨碍Ruby可以做一些同步或异步的工作(可以参考Erlang)。问题的关键在于Rails本身不是线程安全的,如果查看Mongrel的代码则会发现,Mongrel在调用Rails的分发器之前就加了锁,直到Rails处理完这个请求。请参考/var/lib/gems/1.8/gems/mongrel-1.1.4/lib/mongrel/rails.rb第74行(不同的系统上的目录有所不同,不同版本的mongrel,代码出现的位置也可能不同)如下:
@guard.synchronize {
@active_request_path = request.params[Mongrel::Const::PATH_INFO]
Dispatcher.dispatch(cgi,
ActionController::CgiRequest::DEFAULT_SESSION_OPTIONS,
response.body)
@active_request_path = nil
}
我们知道,对于锁的粒度一般是越小越好的,而这里的锁就这是造成问题的关键原因。
假设一个Mongrel当前的请求被阻塞在Rails的代码中(比如一个较长的查询),后续的请求就会被阻塞,假如阻塞的时间足够长,导致队列中请求满了,那么接下来就是出现大量时间花费在上下文切换和锁的争用上。
这就是为什么Rails应该以进程方式来运行的原因。所以之后很多人致力于开发单线程、非阻塞IO的方式来处理请求,这样做的好处是可以减少对连接的创建、关闭的等待时间,以及省去对锁的操作——锁操作是非常昂贵的。但它并不能解决Rails应用程序中被阻塞时的并发问题。同样地,FastCGI也无法解决这个问题。
而新的Ruby框架如Merb,则实现了线程安全,解决了这个问题,因此可以利用线程的方式来提高并发性。Ebb也宣称其线程模式的运行方式在运行Merb可以承受更大的压力。
为了解决这个我问题,我们要做的就是使用多个进程来进行服务,并限制从前端到后端的链接数。
而使用进程方式的问题就在于,进程之间不能共享信息,进程比线程占用更多的资源。我给公司写的程序在启动完毕Mongrel之后,单个进程占用内存为34M,随着访问量的不断增加,内存占用也会逐渐增长,如果遇到大量并发请求,内存会增长地更快。
前端的问题 前面列举的各种前端,除了Swiftiply因为是专门为Ruby设计的,其他的程序都十分通用,网上有非常多的比较,在此我们直接跳过对于前端的测试,直接讨论对于前端的问题。
Apache
Apache的问题前面提到过,Apache占用资源非常多,在Prefork方式下,单个进程占用内存在5至10M,而占用的VMSize则非常巨大,随着服务的连接数增长,实际内存占用空间可以很容易达到内存极限,而VMSize可以达到十几倍于实际内存的数量。虽然Apache和Linux的稳定性让它和系统不至于崩溃,但这确实是很可怕和危险的数字。相对而言,Lighttpd、Nginx等则每个进程只占用1到2兆内存,便可以提供于与Apache相匹配的能力。
而前面也提到了,Rails也最好使用进程方式来运行,Rails占用内存更加巨大,加上为了给进程运行中一些缓冲的空间,一般一台1G内存的VPS建议最多只开10个Mongrel进程,也就只能同时服务10个链接。而如果Apache也与Rails争内存的话,便会使原本就紧张的内存空间更紧张,接着开始使用很多交换分区,CPU便把大量时间花费在内存交换上。所以,除非使用Passenger方式部署Rails应用和在Windows平台下部署,其他情况下推荐考虑别的部署方式。
如果不得不用Apache+Mongrel方式,也不用担心,因为Apache的负载均衡非常强大,不仅支持不同的后端,还实现了链接池的概念,通过smax和max两个水平线来控制到后端的数量,具体可以查看Apache的ProxyPass指令的解释。如下图:
1<=min<=smax<=max<=系统限制在1到min之间是与后端创建的最少的连接数,一般是持久连接,min到smax之间是根据请求数量创建的动态链接的数量,smax到max之间的连接被放入连接池中,被给定一个生存时间ttl,大于max数量的链接将等待timeout时间。其中在Prefork模式下系统限制始终为1,Worker方式下为每个进程的线程数。
有了这些参数,使用Apache+Mongrel的部署方式我们便可以控制链接到Mongrel的链接数。
而且Apache也支持到后端服务器的持久链接,即KeepAlive
Lighttpd
如果采用尚未发布的Lighttpd 1.5,那么基本上可以说是没有什么问题,不仅占用资源少,功能也十分齐全,几乎无可挑剔。即可以支持HTTP后端的负载均衡,也支持FastCGI后端,同时还能限制到后端的链接数,并且可以支持不同的负载均衡算法。
虽然Lighttpd1.5也实现了链接池,但他不像Apache实现了两层的水平线,他只有一个最大链接池尺寸的参数来控制到后端的链接的数量,而没有设计等候池,所以超时时间不容易设置,在后面的测试中会显示出来。
Nginx
Nginx在HTTP分发上性能非常好,但不支持链接数的限制,同时只实现了round-robin算法,而且不支持FastCGI后端的分发。
HAproxy
HAproxy作为一个负载均衡反向代理而言,功能十分强大,他和Apache一样,实现了对后端的两层的连接池,请求的控制也能好,同时占用资源也十分少。由于HAproxy不能服务静态页面,所以我们通常需要将HAproxy和其他几个软件搭配使用,或者在系统的架构上进行一些别的处理。
Swiftiply
Swiftiply用Ruby写成,即便使用了一些C扩展,性能到底如何还是值得怀疑。Swiftiply不仅能实现分发,还能实现虚拟主机的功能来绑定不同域名。但其工作机制比较特殊,是让后端的进程主动链接到它,这样可以非常方便地增加进程。
前后端搭配的测试 各种前端的,我在这里要测试的性能主要是对于动态请求的响应速度,所以本案中的某些配置既没有考虑使用Rewrite或其他方式对静态文件进行单独处理(除了Passenger和Swiftiply默认配置便实现了这个功能),也不考虑测试到前端的KeepAlive请求。主要测试以下的组合:
- Apache + Passenger
- Nginx + Mongrel
- Nginx + Evented Mongrel
- Nginx + Thin
- Swiftiply + Swiftiplied Mongrel
- Swiftiply + Thin
- HAproxy + Mongrel
- HAproxy + Thin
- Lighttpd + Mongrel
- Lighttpd + Thin
- Lighttpd + FastCGI/Socket
- Lighttpd + FastCGI/TCP
做服务器的被测试机器为ThinkPad T43,Intel Pentium M 1.86G,1.5G RAM,系统为Ubuntu 8.04。发送请求的是无线局域网中的另外一台笔记本,运行Vista。两台机器通过TP-Link WR340G+ 801.11g 54MB的无线局域网相连。
前端和后端处于同一台机器上,所有的后端都设为10个进程,绑定于30000-30009端口,Passenger设置为最大生成10个进程,Swiftiply则是绑定于4000端口监听。FastCGI的socket路径为/tmp/rails[0-9].sock。
Apache的配置
Apache版本为2.2.8,编译配置选项如下:
CFLAGS="-march=pentium4 -O3 -pipe -fomit-frame-pointer" ./configure --prefix=/opt/apache2 --disable-authn-file --disable-authn-default --disable-authz-host --disable-authz-groupfile --disable-authz-user --disable-authz-default --disable-auth-basic --disable-include --disable-filter --disable-charset-lite --disable-log-config --disable-env --disable-setenvif --disable-mime --disable-status --disable-autoindex --disable-asis --disable-cgid --disable-cgi --disable-negotiation --disable-dir --disable-actions --disable-userdir --disable-alias --enable-suexec --enable-http --enable-suexec --enable-proxy --enable-proxy-http --enable-proxy-balancer --enable-static-support --enable-static-htpasswd --enable-static-htdigest --enable-static-rotatelogs --enable-static-logresolve --enable-static-htdbm --enable-static-ab --enable-static-checkgid --with-mpm=prefork这个配置尽量减少了Apache所加载的模块,仅启用和测试相关的以提升Apache的性能。另外,这种配置下必须删除rails应用的public目录下默认的.htaccess文件,否则无法使Passenger成功处理静态文件。
Passenger推荐使用Apache的Prefork工作方式,但为了做一个对比,我还会给出Worker方式的Apache配合Passenger的性能比较。
Apache的配置文件httpd.conf为:
ServerRoot "/opt/apache2"
Listen 8080
<IfModule !mpm_netware_module>
<IfModule !mpm_winnt_module>
User shiningray
Group shiningray
</IfModule>
</IfModule>
<IfModule !mpm_netware_module>
PidFile "logs/httpd.pid"
</IfModule>
<IfModule !mpm_winnt_module>
<IfModule !mpm_netware_module>
LockFile "logs/accept.lock"
</IfModule>
</IfModule>
<IfModule mpm_worker_module>
ThreadLimit 20000
ServerLimit 32
StartServers 2
MaxClients 8192
MinSpareThreads 64
MaxSpareThreads 1024
ThreadsPerChild 256
MaxRequestsPerChild 0
</IfModule>
<IfModule mpm_prefork_module>
ServerLimit 1024
StartServers 5
MinSpareServers 5
MaxSpareServers 10
MaxClients 1024
MaxRequestsPerChild 0
</IfModule>
ServerAdmin admin@shiningray.cn
ServerName 127.0.0.1:8080
DocumentRoot "/var/www/"
<IfModule dir_module>
DirectoryIndex index.html
</IfModule>
ErrorLog "logs/error_log"
KeepAlive off
MaxKeepAliveRequests 1024
NameVirtualHost *:8080
LoadModule passenger_module "/var/lib/gems/1.8/gems/passenger-1.0.1/ext/apache2/mod_passenger.so"
RailsSpawnServer /var/lib/gems/1.8/bin/passenger-spawn-server
RailsAutoDetect off
<VirtualHost *:8080>
ServerName localhost
DocumentRoot /home/shiningray/NetBeansProjects/botadmin/public
RailsBaseURI /
RailsEnv "production"
RailsMaxPoolSize 10
</VirtualHost>
Nginx的配置
Nginx 0.6.29,编译配置选项如下:
./configure --prefix=/opt/nginx --cpu-opt=pentium4
配置文件nginx.conf如下:
#user nobody;
worker_processes 1;
events {
worker_connections 1024;
use epoll;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
upstream mongrel {
server 127.0.0.1:30000;
server 127.0.0.1:30001;
server 127.0.0.1:30002;
server 127.0.0.1:30003;
server 127.0.0.1:30004;
server 127.0.0.1:30005;
server 127.0.0.1:30006;
server 127.0.0.1:30007;
server 127.0.0.1:30008;
server 127.0.0.1:30009;
}
server {
listen 8080;
server_name localhost;
root /home/shiningray/NetBeansProjects/botadmin/public;
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect false;
include fastcgi_params;
if (-f $request_filename/index.html) {
rewrite (.*) $1/index.html break;
}
if (-f $request_filename.html) {
rewrite (.*) $1.html break;
}
if (!-f $request_filename) {
#proxy_pass http://mongrel;
#fastcgi_pass unix:/tmp/rails0.sock;
fastcgi_pass 127.0.0.1:9000;
break;
}
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
Swiftiply的配置
我直接通过“gem i swiftiply”来安装了Swiftiply,Swiftiply的配置文件如下:
cluster_address: 0.0.0.0
cluster_port: 8080
daemonize: false
map:
- incoming:
- localhost
- 192.168.1.100
outgoing: 127.0.0.1:4000
default: true
docroot: /home/shiningray/NetBeansProjects/botadmin/public
cache_extensions:
- htm
- html
- txt
HAproxy的配置
HAproxy 1.2.17,编译选项为
make TARGET="linux26" CPU="pentium4"配置文件haproxy.cfg为:
# this config needs haproxy-1.1.28 or haproxy-1.2.1
global
log 127.0.0.1 local0
log 127.0.0.1 local1 notice
maxconn 2000
defaults
log global
mode http
option httplog
option dontlognull
retries 3
redispatch
maxconn 2000
contimeout 5000
clitimeout 50000
srvtimeout 50000
listen localhost 0.0.0.0:8080
balance roundrobin
server mongrel_30000 127.0.0.1:30000 maxconn 1
server mongrel_30001 127.0.0.1:30001 maxconn 1
server mongrel_30002 127.0.0.1:30002 maxconn 1
server mongrel_30003 127.0.0.1:30003 maxconn 1
server mongrel_30004 127.0.0.1:30004 maxconn 1
server mongrel_30005 127.0.0.1:30005 maxconn 1
server mongrel_30006 127.0.0.1:30006 maxconn 1
server mongrel_30007 127.0.0.1:30007 maxconn 1
server mongrel_30008 127.0.0.1:30008 maxconn 1
server mongrel_30009 127.0.0.1:30009 maxconn 1
maxconn参数表示限制到后端的连接数,我会在测试中调整这些参数来看对性能的影响。
Lighttpd的配置
Lighttpd版本为 1.5.0 r1922
编译配置选项为:
./configure --prefix=/opt/lighttpd配置文件lighttpd为
server.modules = (
"mod_rewrite",
"mod_access",
"mod_proxy_core",
"mod_proxy_backend_http",
"mod_proxy_backend_fastcgi")
server.document-root = "/home/shiningray/NetBeansProjects/botadmin/public"
server.bind = "0.0.0.0"
server.port = 8080
server.pid-file = "/opt/lighttpd/logs/lighttpd.pid"
server.username = "shiningray"
server.groupname = "shiningray"
server.errorlog = "/opt/lighttpd/logs/lighttpd.error.log"
url.rewrite-once = ( "^/.*$" => "/dispatch.fcgi" )
$HTTP["url"] =~ "\.fcgi$" {
proxy-core.balancer = "round-robin"
proxy-core.allow-x-sendfile = "enable"
proxy-core.protocol = "fastcgi"
proxy-core.backends = (
"unix:/tmp/rails0.sock",
"unix:/tmp/rails1.sock",
"unix:/tmp/rails2.sock",
"unix:/tmp/rails3.sock",
"unix:/tmp/rails4.sock",
"unix:/tmp/rails5.sock",
"unix:/tmp/rails6.sock",
"unix:/tmp/rails7.sock",
"unix:/tmp/rails8.sock",
"unix:/tmp/rails9.sock"
)
proxy-core.max-pool-size=64
}FastCGI的TCP方式则是将proxy-core-backends参数中的后端改为:
"127.0.0.1:30000",
"127.0.0.1:30001",
"127.0.0.1:30002",
"127.0.0.1:30003",
"127.0.0.1:30004",
"127.0.0.1:30005",
"127.0.0.1:30006",
"127.0.0.1:30007",
"127.0.0.1:30008",
"127.0.0.1:30009",Lighttpd使用HTTP后端的配置文件为:
server.modules = (
"mod_rewrite",
"mod_access",
"mod_proxy_core",
"mod_proxy_backend_http",
"mod_proxy_backend_fastcgi")
server.document-root = "/home/shiningray/NetBeansProjects/botadmin/public"
server.bind = "0.0.0.0"
server.port = 8080
server.pid-file = "/opt/lighttpd/logs/lighttpd.pid"
server.username = "shiningray"
server.groupname = "shiningray"
server.errorlog = "/opt/lighttpd/logs/lighttpd.error.log"
$HTTP["url"] =~ "^.*$" {
proxy-core.balancer = "round-robin"
proxy-core.allow-x-sendfile = "enable"
proxy-core.protocol = "http"
proxy-core.backends = (
"127.0.0.1:30000",
"127.0.0.1:30001",
"127.0.0.1:30002",
"127.0.0.1:30003",
"127.0.0.1:30004",
"127.0.0.1:30005",
"127.0.0.1:30006",
"127.0.0.1:30007",
"127.0.0.1:30008",
"127.0.0.1:30009",
)
proxy-core.max-pool-size=1
}
proxy-core.max-pool-size参数表示限制到后端的连接数,还将分别调整此参数来看对性能的影响。
测试结果 HAproxy和Lighttpd的测试需要调整很多参数,我们先看看无需调整参数的几种方案的测试结果,我同样除了原始数据的折线图,还会给出B样条的图以更清晰地看到结果:
从图上我们看到Nginx+Mongrel的方式性能很稳定,但在并发量小于150的情况下与其他方案相比还是差很多的。
Nginx+Thin/Evented Mongrel两种方式的性能则相差不大,毕竟都是使用的EventMachine。
Swiftiply的两种方式都体现出了很高的性能,尤其是Swiftiply+Swiftiplied Mongrel令人印象深刻,即使在500的并发量左右,性能依然保持稳定。
Apache+Passenger模式在低并发(<=300)的情况下效率很高,但随着并发量上升,Apache的两种工作模式本身的效率下降得就很快,Prefork模式在大于450的情况下降到了0(我认为是出现了TCP错误导致AB测试中断)。
这个测试中,除了Nginx,其他的搭配方式Swiftiply和Passenger,应该每次都只给后端一个请求,同时也是建立的持久链接。
HAproxy/Mongrel的测试结果
通过对HAproxy的maxconn参数的调整,得到了如上图的测试结果,我们不难发现在maxconn=1的情况下是效率最高的,这印证了前面对后端缺点的分析。因为在限制了每次只有一个链接之后,Mongrel的进程减少了锁和上下文切换的开销,所以得到了很稳定的性能,另外我们还可以注意到,随着maxconn越来越大,最后达到50的时候,这时候Mongrel进程中对于锁和上下文切换的开销也趋于平稳,情况变成了和Nginx/Mongrel的情况一样。
通过对比,我们可以发现,利用HAproxy限制到Mongrel的链接数为1,可以比Nginx+Mongrel的方式性能提高23%~28%,不过相比Passenger/Swiftiply方式而言,还是差一点点,但性能依然十分稳定。
这也是为什么ThoughtWorks的Rubyworks采用了HAproxy的缘故,我觉得在Rubyworks推出的当时是非常正确的选择,因为当时没有其他选择。
HAproxy/Thin的测试结果
由于Thin没有锁和上下文切换的开销,因此限制maxconn在测试结果上不如对Mongrel的效果那么明显。但基本上也可以看出来,将链接到后端的连接数限制在较小的范围内会对性能和稳定性有更好的帮助。
Lighttpd/Mongrel的测试结果
Lighttpd+Mongrel的图像与HAproxy+Mongrel的非常不同,尤其是在限制到后端的链接效果上。我在测试结果中发现了大量的504Gatewaytimeout错误返回,从而导致了响应速度的降低。随着链接限制参数的变大,504错误越来越少。我们可以发现在并发量小于100的时候,其效果还是和HAproxy类似的。当链接限制大到一定程度,其效果和Nginx+Mongrel的方式也是一样的。
Lighttpd/Thin的测试结果
Lighttpd搭配Thin的情况同样出现了Mongrel一样的情况,在max-pool-size参数为1的时候出现了大量的504错误返回,并随着这个参数的增加错误数减少。
Lighttpd+Thin的方式在不限制连接数的情况下性能要大大优于Nginx+Thin和HAproxy+Thin的方式。
Lighttpd/FastCGI的测试结果
通过Socket方式
通过TCP方式
我们可以发现Lighttpd的FastCGI方式走TCP或Socket在性能方面没有太大差别,但限制链接数容易造成Lighttpd直接给出错误返回,随着连接数限制的放宽,错误数也减少,响应速度也变得稳定。
根据前面对后端的测试,无论何种后端都应该在低链接的情况下有更好的表现,Lighttpd为何在限制了连接数之后反而有更过504错误呢,我认为是Lighttpd未实现像Apache和HAproxy的双重链接池的功能,同时Lighttpd的默认的超时时间又只有10秒钟。在Apache和HAproxy的情况中,当链接未进入某个后端服务器的等待队列时,会等待Timeout时间,而进入了后端等待队列之后会重新等待TTL的时间,这样就避免了快达到Timeout的时候进入等待队列没多久就被放弃的情况。当然Apache和HAproxy的Timeout和TTL参数也需要根据系统的性能和要求小心调整。而对于Lighttpd则可以考虑适当增大Timeout时间。
分析和小结
我先来将本案中的各种部署方式的性能排个名次,以下是后各种方案在并发量>=10的情况下的平均值(去掉出现0值的情况):
前端 |
后端 |
平均每秒响应数 |
最大链接限制 |
Lighttpd |
FastCGI/TCP |
215.33 |
64 |
Lighttpd |
FastCGI/Socket |
214.65 |
64 |
Lighttpd |
Thin |
196.16 |
64 |
Swiftiply |
Swiftiplied Mongrel |
191.33 |
N/A |
HAproxy |
Thin |
188.73 |
10 |
Swiftiply |
Thin(Swiftiplied) |
178.96 |
N/A |
Apache2.2/Prefork |
Passenger |
173.02 |
N/A |
HAproxy |
Mongrel |
170.4 |
1 |
Apache2.2/Worker |
Passenger |
163.9 |
N/A |
Lighttpd |
Mongrel |
149.85 |
64 |
Nginx |
Evented Mongrel |
149.78 |
N/A |
Nginx |
Thin |
143.88 |
N/A |
Nginx |
Mongrel |
138.86 |
N/A |
在这个表中,Lighttpd的三种方案占据了前三位,Lighttpd+FastCGI是性能最高的部署方式。这种方式比另一种流行方案Nginx+Mongrel的方式性能提升了高达50%!
FastCGI的好处在此体现出来:
- 二进制协议,无需HTTP的解析
- 与前端可以建立持久链接
- 没有锁和上下文切换的开销
另外Lighttpd相对于Nginx的优势在于请求和响应的接收缓冲区很大,省去多次接收和发送的开销。
Lighttpd+Thin的方式的性能列第三位,这点似乎出乎意料之外,但实际上是因为Lighttpd 1.5支持对HTTP后端建立HTTP KeepAlive链接。在第一部分对后端单独的测试中,小并发下的Thin的KeepAlive测试性能并不比FastCGI差,同时Thin实现了非阻塞IO,而FastCGI则是阻塞式的。相反,HAproxy和Nginx则都不支持HTTP KeepAlive。
而Swiftiply的方式也显示出了强劲的性能,应该是得益于它的“让后端主动连接到Swiftiply”的这种特殊的结构。
当前备受关注的Passenger的部署方式在本案中并没有显示出特别的性能上的优势,不过如果将并发链接数放在300以内,则Apache2.2/Prefork + Passenger的部署方式的平均每秒响应数上升为204.03,这样看来,倘若为Apache进行一些优化配置,依然不失为一种高效的部署方案。而同时Passenger又是最容易配置的一种方案,能达到这种效果已经非常令人满意。
HAproxy + Mongrel并限制链接数为1,则是一种稳定、保守的部署方式,虽然在这里性能不出众,但是稳定性非常好。
最后,与Nginx相关的三种方案都排在了该榜的末尾,由于Nginx的反向代理负载均衡缺少一些高级的特性以及Rails本身的特性而导致其不适合单独应用在Rails程序的部署上:
- 缺少到后台服务器端的链接数限制的能力,这导致了Mongrel在接受大量请求时将时间消耗在上下文切换和锁的争用上。
- 缺乏建立到后台服务器端的持久链接的能力,这导致了在链接的打开、建立、关闭上花费了额外的开销。
延伸 Windows操作系统
由于*nix操作系统中,可以替代Apache的选择很多,而Windows下基本上只能使用Apache2.2+Mongrel的方式了,想使用Thin的朋友要记得单独安装EventMachine 0.8.1 ,目前最新的Windows安装包。
我给出一个比较合理的Apache2.2的配置,最简化的配置文件如下:
ThreadsPerChild 1024
MaxRequestsPerChild 0
ServerRoot "C:/Apache2"
Listen 80
KeepAlive off
KeepAliveTimeout 15
Timeout 30
MaxKeepAliveRequests 1024
LoadModule log_config_module modules/mod_log_config.so
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_balancer_module modules/mod_proxy_balancer.so
LoadModule proxy_http_module modules/mod_proxy_http.so
LoadModule rewrite_module modules/mod_rewrite.so
LoadModule status_module modules/mod_status.so
ServerAdmin admin@shiningray.cn
ServerName shiningray.cn
DocumentRoot "D:/wwwroot/rails/public"
ErrorLog logs/error.log
LogLevel warn
<IfModule log_config_module>
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
LogFormat "%h %l %u %t \"%r\" %>s %b" common
<IfModule logio_module>
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio
</IfModule>
CustomLog logs/access.log common
</IfModule>
<Proxy balancer://mongrels>
BalancerMember http://127.0.0.1:30000 max=10 smax=1
BalancerMember http://127.0.0.1:30001 max=10 smax=1
#在这里放更多的后端服务器
</Proxy>
ProxyRequests off
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^/(.*)$ balancer://mongrels%{REQUEST_URI} [QSA,P,L]其中,smax=1表示限制到后端的最大链接数为1,max=10表示等待队列为10。如果后端是Mongrel,这样就可以解决Mongrel接受大量请求对锁和上下文切换的消耗。
而如果后端采用了Thin,根据前面的测试结果,应该打开KeepAlive功能,即在每个BalancerMember后面加上keepalive=on,并且适当提升max和smax的值,以充分利用Thin的特性。关于这些参数可以参考ProxyPass指令的解释。
在本文中就不对该平台下的部署方式进行性能测试了,这种方案通常是在对遗留项目的迁移中才会出现,建议Rails应用还是最终应该部署在*nix的平台上以达到最好的性能。
其他有意思的部署方式
当然,除了前面的几种方案之外,我们可以还可以根据实际情况采用不同的组合来实现功能,下面我给出几个复杂一些的方案,希望能抛砖引玉。
一、虽然Nginx不能限制到对后端的链接,而HAproxy又不支持静态文件,那么二者结合会怎样呢?我在公司的一台CentOS 3的服务器上便使用的是Nginx+HAproxy+Mongrel的方式。由于这个部署方式是对HAproxy+Mongrel在外面套一层,性能基本基本接近没有太大差别,便不放测试测试数据了。
二、之前提到了Nginx不支持对FastCGI的后端进行分发,似乎有些遗憾,但我们也提到HAproxy也可以做TCP转发的负载均衡器,利用Nginx+HAproxy来对FastCGI的后端做请求分发效果会如何呢?
于是我做了个测试:
HAproxy的配置改为:
# this config needs haproxy-1.1.28 or haproxy-1.2.1
global
log 127.0.0.1 local0
log 127.0.0.1 local1 notice
#log loghost local0 info
maxconn 2000
#chroot /usr/share/haproxy
#uid 99
#gid 99
#daemon
#debug
#quiet
defaults
log global
mode http
option httplog
option dontlognull
retries 3
redispatch
maxconn 2000
contimeout 5000
clitimeout 50000
srvtimeout 50000
listen test 0.0.0.0:9000
mode tcp
balance roundrobin
server mongrel_30000 127.0.0.1:30000 maxconn 8
server mongrel_30001 127.0.0.1:30001 maxconn 8
server mongrel_30002 127.0.0.1:30002 maxconn 8
server mongrel_30003 127.0.0.1:30003 maxconn 8
server mongrel_30004 127.0.0.1:30004 maxconn 8
server mongrel_30005 127.0.0.1:30005 maxconn 8
server mongrel_30006 127.0.0.1:30006 maxconn 8
server mongrel_30007 127.0.0.1:30007 maxconn 8
server mongrel_30008 127.0.0.1:30008 maxconn 8
server mongrel_30009 127.0.0.1:30009 maxconn 8
Nginx的配置改为:
worker_processes 1;
events {
worker_connections 1024;
use epoll;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
server {
listen 8080;
server_name localhost;
root /home/shiningray/NetBeansProjects/botadmin/public;
location / {
include fastcgi_params;
if (-f $request_filename/index.html) {
rewrite (.*) $1/index.html break;
}
if (-f $request_filename.html) {
rewrite (.*) $1.html break;
}
if (!-f $request_filename) {
fastcgi_pass 127.0.0.1:9000;
break;
}
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}据我测试,此部署方案的性能也可以与Lighttpd的几种一较高下,但毕竟因为多了一层,还是略占下风。
这两种方案部署上更为繁琐,小型应用上其实只需要考虑前面的两层方案便可,在此不做详细的评测了。
其它问题除了对部属方案的性能考虑之外,我们还需要考虑一些别的问题。
Lighttpd虽然方案性能最高,但是有个不便之处,Lighttpd的mod_rewrite功能不如Apache和Nginx强大,他不能判断请求的文件是否存在,如果不存在便向后端发送,这对于小型网站并不方便,必须根据情况配置复杂的rewrite规则。值得一提的是,Lighttpd可以使用Lua脚本进行更高级的rewrite。该功能的ticket被关闭又被打开:http://trac.lighttpd.net/trac/ticket/985 -Shiningray 5/6/08 7:22 PM
Mongrel后端的启动是通过mongrel_cluster启动的,我们只要安装这个gem便可,如果要添加为自启动脚本可以利用mongrel_cluster自带的init脚本。但是这些脚本不能实现当mongrel进程崩溃、退出后的重新启动,同时,如果配置不恰当,当mongrel进程被强制杀死或系统宕机之后,mongrel遗留的pid文件会导致无法启动mongrel进程,必须先删除这些文件(Mongrel_cluster提供了--clean选项来事先清除无用pid)。FastCGI进程也有同样的问题。
有一个非常好的进程监控程序称之为Monit。Rubyworks也搭配了Monit来监控Mongrel的进程,而不使用Mongrel_cluster。并且monit可以限制mongrel的进程的内存用量,防止出现内存溢出的问题等。同时monit也可以监控其他的进程如我们的前端。
总结 Rails的部署方式的核心问题就在于解决一、Rails本身是非线程安全,二、Ruby的线程性能差这两个问题上。本文列举了十余种常见的Rails部署方案,其中基于Lighttpd 1.5的几种解决方案都从原理上很好地解决了Rails部署的两大问题,而且有着不俗的性能。由于本案中的测试仅建立在我为公司的服务器端所做测试的基础上,并且设计、执行得不够严谨,仅仅具有一定的参考意义。另外限于我的能力和精力问题,通过JRuby借助JavaEE平台的部署方案未能进行评测,我相信也是很有潜力的方案。
不同的部署方式都有各自的优势,大家需要根据各自所开发的应用的特点和服务器特点来选择恰当的部署方式,例如跨平台性、易用性。
这些方案虽然是针对Ruby on Rails应用的,但是其中的原理是通用的,也希望能对大家在其他应用的部署和架构上有些启发。
仅作为自己的一个学习参考,如有侵犯作者权限,请通知删除!!
相关推荐
内容概要:本文详细介绍了考虑阶梯式碳交易与供需灵活双响应的综合能源系统优化调度方法。在供给侧,引入了有机朗肯循环(ORC)实现热电联产机组的灵活响应;在需求侧,提出电、热、气负荷之间的可替代性,以提高能源利用效率。构建了以最小化碳排放成本、购能成本、弃风成本和需求响应成本为目标的优化调度模型,并采用MATLAB和CPLEX进行了模型构建和求解。文中提供了具体的代码示例,展示了如何处理热电耦合、负荷替代和阶梯式碳交易等问题。 适合人群:从事能源系统优化、电力系统调度、碳交易等相关领域的研究人员和技术人员。 使用场景及目标:适用于需要优化能源系统调度、降低成本并减少碳排放的实际应用场景。目标是帮助读者理解和掌握如何通过先进的技术和算法实现更加灵活和高效的能源调度。 其他说明:文章提供了完整的代码实现和服务支持,包括12种典型场景的数据集和预设模型,方便读者快速上手实践。
内容概要:本文详细介绍了一个利用欧姆龙CP1H PLC及其CIF11通讯板与三台东元N310变频器进行通讯的实战案例。主要内容涵盖硬件配置(包括接线方式和终端电阻设置)、变频器参数设置(如波特率、站号等)、PLC编程(含频率设定、实际频率和输出电压读取的具体指令及其实现方法)、以及调试过程中遇到的问题和解决方案。此外,还提供了关于如何扩展更多变频器的方法,强调了通讯稳定性和高效性的优化措施。 适合人群:从事工业自动化领域的工程师和技术人员,尤其是那些需要掌握PLC与变频器通讯技能的人群。 使用场景及目标:适用于需要对多个变频器进行集中控制和监测的应用场合,如工厂生产线、电力系统等。主要目的是提高系统的集成度和可靠性,降低维护成本。 其他说明:文中不仅给出了详细的代码片段,还包括了许多宝贵的实践经验,对于初学者来说是非常好的参考资料。同时,作者也提到了一些常见的陷阱和注意事项,有助于读者少走弯路。
内容概要:本文详细介绍了如何在Simulink中构建TCR+FC型静止无功补偿器(SVC)的仿真模型。首先,文章解释了TCR(晶闸管控制电抗器)和FC(固定电容器)的工作原理及其在电力系统中的重要性。接着,逐步讲解了模型搭建的关键步骤,包括晶闸管参数设置、触发脉冲生成、滤波器设计以及控制策略的选择。文中特别强调了触发角控制对补偿效果的影响,并提供了具体的MATLAB代码示例。此外,作者分享了许多实践经验,如如何应对现场环境变化带来的参数偏差、如何防止谐振等问题。最后,通过对不同工况下仿真结果的分析,展示了该模型在改善电压稳定性、提高功率因数方面的显著效果。 适合人群:从事电力系统研究和技术开发的专业人士,尤其是那些希望深入了解SVC工作原理及其仿真方法的研究人员和工程师。 使用场景及目标:适用于需要进行电力系统无功补偿装置性能评估、优化设计的研究机构或企业。主要目标是在确保系统稳定性的前提下,最大化提升无功补偿效率,降低谐波污染,从而保障电网的安全运行。 其他说明:文中不仅提供了详细的建模指导,还包括许多实用的小贴士和注意事项,帮助读者避开常见陷阱,快速掌握核心技术要点。同时,附带的实际案例分析有助于加深理解,使读者能够将所学应用于实际工程项目中。
# 压缩文件中包含: 中文文档 jar包下载地址 Maven依赖 Gradle依赖 源代码下载地址 # 本文件关键字: jar中文文档.zip,java,jar包,Maven,第三方jar包,组件,开源组件,第三方组件,Gradle,中文API文档,手册,开发手册,使用手册,参考手册 # 使用方法: 解压最外层zip,再解压其中的zip包,双击 【index.html】 文件,即可用浏览器打开、进行查看。 # 特殊说明: ·本文档为人性化翻译,精心制作,请放心使用。 ·只翻译了该翻译的内容,如:注释、说明、描述、用法讲解 等; ·不该翻译的内容保持原样,如:类名、方法名、包名、类型、关键字、代码 等。 # 温馨提示: (1)为了防止解压后路径太长导致浏览器无法打开,推荐在解压时选择“解压到当前文件夹”(放心,自带文件夹,文件不会散落一地); (2)有时,一套Java组件会有多个jar,所以在下载前,请仔细阅读本篇描述,以确保这就是你需要的文件;
智云物业小程序v3.5.0高级版 微信 支付宝前端 版本号:3.5.0智云物业 抄表可以直接录入表号 社区发图多由5张改为9张 添加付出通道对接 车位锁bug批改 细节调整和优化 功能特色: 1. 可视化楼宇房产管理,一键生成楼宇房产(支持EXCEL导入) 2. 住户管理(业主、成员、租户),严格、宽松和自由三种注册方式 3. 报修和投诉建议完整处理流程(派单与抢单),内部工单处理(派单与抢单) 4. 智能门禁(微信开门、定位防骚扰、开门日志)、人脸识别、蓝牙 5. 商铺和车位管理,一键生成或EXCEL导入 6. 多收费项目管理,批量生成账单,前后台收银,可视化管理 7. 社区论坛、邻里互动、新动态 8. WQ独立后台、物业独立后台,权限角色完全分开 9. 版权自定义设置、页面自定义图标及链接 10. 统计分析报表、打通WQ会员、会员组及积分 11. 物业手机端住户管理、上门收费、账单核销、抄表录入、巡更 12. 线下周边商家(集积分、支付、活动、红包于一体) 13. 积分红包、挪车服务、打包小程序、智能充电站、自助智能设备(如:洗车机、饮水机等) 14. 全局权限控制、公众号授权、自定义系统帮助 15. 对接多家车牌识别管理系统,在线缴费、办理月卡、统计报表 16.?快递驿站、活动管理(投票、报名、问卷)、管理看板
内容概要:本文详细介绍了在一个新能源物料输送系统中,利用西门子S7-1200 PLC和昆仑通态触摸屏实现物料输送控制的具体方法。主要内容涵盖硬件配置(如PLC、称重仪表、RS485通信模块)、通信配置(如RS485参数设置)、软件开发(如博途V16编程、模拟量采集、物料输送控制逻辑)以及触摸屏组态开发等方面。文中不仅提供了具体的配置步骤和技术细节,还分享了许多实际开发中的经验和常见问题解决方法。 适合人群:自动化领域的工程师和技术人员,尤其是那些正在从事或计划从事PLC控制系统的开发和维护工作的人员。 使用场景及目标:适用于需要开发类似物料输送系统的工程项目,旨在帮助读者掌握PLC控制系统的开发技能,提高系统稳定性和可靠性,减少开发过程中的错误和问题。 其他说明:文中提到的实际案例和开发经验对于理解和解决工业自动化项目中的常见问题非常有帮助。同时,文中提供的代码片段和配置示例可以直接应用于实际项目中,方便读者快速上手。
内容概要:本文详细介绍了如何在Matlab/Simulink环境下构建光伏储能系统与虚拟同步发电机(VSG)并网的模型。首先,文章阐述了整体思路,即实现直流侧光储与VSG并网的完美配合。接着,分别讲解了光伏部分、储能部分和VSG部分的具体实现方法,包括光伏电池模型的选择、储能电池的参数设置以及VSG控制算法的设计。此外,文章还讨论了光照强度变化的设置及其对系统的影响,并提供了详细的波形分析。最后,针对模型调试过程中遇到的问题提出了有效的解决方案。 适合人群:从事电力电子、新能源发电领域的研究人员和技术人员,尤其是熟悉Matlab/Simulink工具的用户。 使用场景及目标:适用于希望深入了解光伏储能系统与虚拟同步发电机并网机制的研究人员和技术人员。主要目标是掌握如何在Matlab/Simulink中搭建和优化此类模型,以便更好地应用于实际工程实践中。 其他说明:文中提供的代码片段和调试技巧对于初学者非常有帮助,同时也为高级用户提供了一些优化建议。通过对不同参数的调整,如虚拟惯量、阻尼系数等,可以进一步提高系统的稳定性和响应速度。
【蓝桥杯EDA】客观题解析
表格可以详细查询到商用车CAN通信里每个信号具体的定义,SPN,每一位信号的定义
内容概要:本文详细介绍了直驱永磁风机的Simulink仿真模型,涵盖了机侧和网侧控制、低电压穿越控制(chopper电路控制)、风速模拟及最大功率点跟踪(MPPT)。机侧控制采用了内外双环结构,通过零d轴电流(ZDC)控制降低铜损,提高效率;MPPT则通过最优转矩(OTC)控制实现。网侧控制包括并网和脱网两种模式,分别采用双闭环解耦控制和闭环无源逆变控制。低电压穿越控制通过chopper电路确保电网电压异常时风机的稳定运行。风速模拟部分使用了复杂的风速模型,使仿真更加接近实际情况。此外,文中还提到了详细的参数设定和调试经验,以及相关文献的支持。 适合人群:从事风电系统设计、仿真建模的研究人员和技术人员,尤其是对直驱永磁风机及其控制系统感兴趣的工程师。 使用场景及目标:适用于需要深入了解直驱永磁风机Simulink仿真的研究人员和技术人员。主要目标是掌握直驱永磁风机的控制策略,包括内外双环控制、低电压穿越控制、风速模拟及MPPT的具体实现方法,以便应用于实际项目中。 其他说明:文中提供的代码片段和参数设定有助于读者更好地理解和应用这些控制策略。同时,参考文献也为进一步研究提供了理论依据。
内容概要:本文详细介绍了如何在Simulink环境中构建永磁同步电机(PMSM)的多故障诊断模型,特别是针对绕组匝间短路和转子偏心故障的联合诊断。文章首先展示了如何通过MATLAB代码实现绕组电阻变化模型,解释了故障注入的关键参数设置及其背后的物理意义。接着讨论了混合故障建模的方法,强调了机械偏心和电气短路之间的耦合关系,并提供了具体的Simulink模块连接方式。文中还探讨了多种先进的故障特征提取技术,如改进的S变换、小波包分解以及经验模态分解,并推荐使用MATLAB的signalDiagnosticDesigner工具来自动生成特征提取代码。此外,文章介绍了不同类型的观测器设计,包括磁链观测器和滑模观测器,并分享了一些实用的经验技巧。最后,文章提出了几种有效的故障分类算法,如改进的KNN和支持向量机结合长短期记忆网络的混合模型。 适合人群:从事电机控制系统设计的研究人员和技术工程师,尤其是那些对永磁同步电机故障诊断感兴趣的从业者。 使用场景及目标:适用于希望深入了解永磁同步电机内部故障机制并在Simulink平台上进行仿真的专业人士。主要目标是提高故障检测精度,优化故障处理策略,确保系统的稳定性和可靠性。 其他说明:文中提供的代码片段和建模思路可以帮助读者快速入门并掌握复杂的故障诊断流程。同时,作者还分享了许多宝贵的实践经验,有助于避免常见的错误和陷阱。
内容概要:本文详细介绍了三菱Q系列11轴运动控制项目的实施细节,涵盖PLC程序、触摸屏程序、电气清单及完整电路图。PLC程序采用分工位编辑,确保各工位独立控制,便于调试和维护。触摸屏程序实现了对各工位的实时监控和参数修改,增强了系统的灵活性。电气清单详尽列出所有电气元件及其规格,电路图展示了元件间的连接关系,有助于现场布局和故障排查。此外,文中还涉及定位模块和模拟量模块的应用,提升了系统的控制精度和稳定性。 适合人群:从事工业自动化领域的工程师和技术人员,尤其是那些负责多轴运动控制系统的开发和维护人员。 使用场景及目标:适用于需要进行复杂多轴运动控制的工业生产线,旨在提高生产效率、降低维护成本,并提供详细的编程和设计指导。 其他说明:文章不仅提供了具体的代码示例和电路图,还包括了许多实用的设计技巧和注意事项,如异常处理机制、信号隔离方法以及变量命名规范等,这些都是实际项目中非常宝贵的经验总结。
在当今智慧城市的建设浪潮中,智慧环卫作为城市管理的重要组成部分,正以其独特的魅力引领着环卫行业的变革。本方案旨在通过一系列高科技手段,如物联网、大数据、云计算等,全面提升环卫作业效率与管理水平,为城市居民创造更加清洁、宜居的生活环境。 一、智慧环卫系统概述与核心亮点 智慧环卫系统是一个集机械化保洁、垃圾清运、设施管理、事件指挥调度等多功能于一体的综合性管理平台。其核心亮点在于通过高精度定位、实时监控与智能分析,实现环卫作业的精细化管理。例如,机械化保洁管理子系统能够实时监控机扫车、洒水车等作业车辆的运行状态,自动规划最优作业路线,并根据作业完成情况生成考核评价报表,极大地提高了作业效率与服务质量。同时,垃圾清运管理子系统则通过安装GPS定位设备和油量传感器,对清运车辆进行全方位监控,确保垃圾清运过程的规范与高效,有效解决了城市垃圾堆积与随意倾倒的问题。此外,系统还配备了垃圾箱满溢报警系统,通过智能感应技术,当垃圾箱内垃圾达到预设高度时自动报警,提醒作业人员及时清运,避免了因垃圾满溢而引发的居民投诉与环境污染。 二、智慧环卫系统的趣味性与知识性融合 智慧环卫系统不仅实用性强,还蕴含着丰富的趣味性与知识性。以餐厨垃圾收运管理子系统为例,该系统通过为餐厨垃圾收运车辆安装GPS定位、车载称重、视频监控等多种感知设备,实现了对餐厨垃圾收运过程的全程监控与智能管理。作业人员可以通过手机APP实时查看车辆位置、行驶轨迹及收运情况,仿佛在玩一场现实版的“垃圾追踪游戏”。同时,系统还能自动生成餐厨垃圾收运统计报表,帮助管理人员轻松掌握收运量、违规情况等关键数据,让数据管理变得既科学又有趣。此外,中转站视频监控子系统更是将趣味性与实用性完美结合,通过高清摄像头与双向语音对讲功能,实现了对中转站内外环境的实时监控与远程指挥,让管理人员足不出户就能掌控全局,仿佛拥有了一双“千里眼”和一对“顺风耳”。 三、智慧环卫系统的未来展望与社会价值 随着科技的不断进步与智慧城市建设的深入推进,智慧环卫系统将迎来更加广阔的发展前景。未来,智慧环卫系统将更加注重数据的深度挖掘与分析,通过大数据与人工智能技术,为城市环卫管理提供更加精准、高效的决策支持。同时,系统还将加强与其他城市管理系统的互联互通,实现资源共享与协同作战,共同推动城市管理的智能化、精细化水平。从社会价值来看,智慧环卫系统的推广与应用将有效提升城市环境卫生质量,改善居民生活环境,提升城市形象与竞争力。此外,系统还能通过优化作业流程、减少资源浪费等方式,为城市可持续发展贡献重要力量。可以说,智慧环卫系统不仅是城市管理的得力助手,更是推动社会进步与文明发展的重要力量。
内容概要:本文详细介绍了基于MATLAB的车牌识别技术,涵盖了从图像预处理到最终字符识别的完整流程。首先,文章强调了MATLAB环境配置及相关图像处理工具箱的重要性。接着,逐步展示了核心代码片段,如图像读取、灰度转换、边缘检测、形态学操作、轮廓提取、车牌区域筛选等关键技术。此外,还探讨了字符分割方法,包括垂直投影法和连通域分析,并介绍了模板匹配用于字符识别的具体实现。文中不仅提供了代码示例,还附带了详细的Word版解析,解释了各个函数的作用及参数选择依据,帮助读者深入理解每一环节的工作机制。 适合人群:对图像处理和车牌识别感兴趣的初学者、有一定编程基础的研究人员和技术爱好者。 使用场景及目标:适用于学术研究、教学演示以及小型项目的快速原型开发。主要目标是使读者能够掌握车牌识别的基本原理和技术细节,从而应用于实际场景中。 其他说明:文章特别指出了一些常见问题及其解决办法,例如如何应对复杂光照条件、字符粘连等问题,并给出了具体的优化建议。同时,强调了代码实现过程中需要注意的各种细节,如参数调整、图像预处理等,以提高识别精度。
1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。
1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。
1.版本:matlab2014/2019a/2024a 2.附赠案例数据可直接运行matlab程序。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。
街道行政区划shp,wgs84坐标系
easyocr安装包和模型