19个心得 明明白白说Linux下的负载均衡
二、F5是通过硬件的方式来实现负载均衡,它较多应用于CDN系统,用于squid反向加速集群的负载均衡,是专业的硬件负载均衡设备,尤其适用于每秒新建连接数和并发连接数要求高的场景;LVS和Nginx是通过软件的方式来实现的,但稳定性也相当强悍,在处理高并发的情况也有相当不俗的表现。
三、Nginx对网络的依赖较小,理论上只要ping得通,网页访问正常,nginx就能连得通,nginx同时还能区分内外网,如果是同时拥有内外网的节点,就相当于单机拥有了备份线路;lvs就比较依赖于网络环境,目前来看服务器在同一网段内并且lvs使用direct方式分流,效果较能得到保证。
四、目前较成熟的负载均衡高可用技术有LVS+Keepalived、Nginx+Keepalived,以前Nginx没有成熟的双机备份方案,但通过shell脚本监控是可以实现的,有兴趣的可具体参考我在51cto上的项目实施方案;另外,如果考虑Nginx的负载均衡高可用,也可以通过DNS轮询的方式来实现,有兴趣的可以参考张宴的相关文章。
五、集群是指负载均衡后面的web集群或tomcat集群等,但现在的集群意义泛指了整个系统架构,它包括了负载均衡器以及后端的应用服务器集群等,现在许多人都喜欢把Linux集群指为LVS,但我觉得严格意义上应该区分开。
六、负载均衡高可用中的高可用指的是实现负载均衡器的HA,即一台负载均衡器坏掉后另一台可以在<1s秒内切换,最常用的软件就是Keepalived和Heatbeat,成熟的生产环境下的负载均衡器方案有Lvs+Keepalived、Nginx+Keepalived。
七、LVS的优势非常多:①抗负载能力强;②工作稳定(因为有成熟的HA方案);③无流量;④基本上能支持所有的应用,基于以上的优点,LVS拥有不少的粉丝;但世事无绝对,LVS对网络的依赖性太大了,在网络环境相对复杂的应用场景中,我不得不放弃它而选用Nginx。
八、Nginx对网络的依赖性小,而且它的正则强大而灵活,强悍的特点吸引了不少人,而且配置也是相当的方便和简约,小中型项目实施中我基本是考虑它的;当然,如果资金充足,F5是不二的选择。
九、大型网站架构中其实可以结合使用F5、LVS或Nginx,选择它们中的二种或三种全部选择;如果因为预算的原因不选择F5,那么网站最前端的指向应该是LVS,也就是DNS的指向应为lvs均衡器,lvs的优点令它非常适合做这个任务。重要的ip地址,最好交由lvs托管,比如数据库的ip、webservice服务器的ip等等,这些ip地址随着时间推移,使用面会越来越大,如果更换ip则故障会接踵而至。所以将这些重要ip交给lvs托管是最为稳妥的。
十、VIP地址是Keepalived虚拟的一个IP,它是一个对外的公开IP,也是DNS指向的IP;所以在设计网站架构时,你必须向你的IDC多申请一个对外IP
十一、在实际项目实施过程中发现,Lvs和Nginx对https的支持都非常好,尤其是LVS,相对而言处理起来更为简便。
十二、在LVS+Keepalived及Nginx+Keepalived的故障处理中,这二者都是很方便的;如果发生了系统故障或服务器相关故障,即可将DNS指向由它们后端的某台真实web,达到短期处理故障的效果,毕竟广告网站和电子商务网站的PV就是金钱,这也是为什么要将负载均衡高可用设计于此的原因;大型的广告网站我就建议直接上CDN系统了。
十三、现在Linux集群都被大家神话了,其实这个也没多少复杂;关键看你的应用场景,哪种适用就选用哪种,Nginx和LVS、F5都不是神话,哪种方便哪种适用就选用哪种。
十四、另外关于session共享的问题,这也是一个老生长谈的问题了;Nginx可以用ip_hash机制来解决session的问题,而F5和LVS都有会话保持机制来解决这个问题,此外,还可以将session写进数据库,这也是一个解决session共享的好办法,当然这个也会加重数据库的负担,这个看系统架构师的取舍了。
十五、我现在目前维护的电子商务网站并发大约是1000左右,以前的证券资讯类网站是100左右,大型网上广告大约是3000,我感觉web层的并发越来越不是一个问题;现在由于服务器的强悍,再加上Nginx作web的高抗并发性,web层的并发并不是什么大问题;相反而言,文件服务器层和数据库层的压力是越来越大了,单NFS不可能胜任目前的工作,现在好的方案是moosefs和DRDB+Heartbeat+NFS;而我喜欢的Mysql服务器,成熟的应用方案还是主从,如果压力过大,我不得不选择oracle的RAC双机方案。
十六、现在受张宴的影响,大家都去玩Nginx了(尤其是作web),其实在服务器性能优异,内存足够的情况下,Apache的抗并发能力并不弱,整个网站的瓶颈应该还是在数据库方面;我建议可以双方面了解Apache和Nginx,前端用Nginx作负载均衡,后端用Apache作web,效果也是相当的好。
十七、Heartbeat的脑裂问题没有想象中那么严重,在线上环境可以考虑使用;DRDB+Heartbeat算是成熟的应用了,建议掌握。我在相当多的场合用此组合来替代EMC共享存储,毕竟30万的价格并不是每个客户都愿意接受的。
十八、无论设计的方案是多么的成熟,还是建议要配置Nagios监控机来实时监控我们的服务器情况;邮件和短信报警都可以开启,毕竟手机可以随身携带嘛;有条件的还可以购买专门的商业扫描网站服务,它会每隔一分钟扫描你的网站,如果发现没有alive会向你的邮件发警告信息或直接电话联系。
十九、至少网站的安全性问题,我建议用硬件防火墙,比较推荐的是华赛三层防火墙+天泰web防火墙,DDOS的安全防护一定要到位;Linux服务器本身的iptables和SElinux均可关闭,当然,端口开放越少越好。
如何诊断和解决CPU高度消耗(100%)的数据库问题
很多时候我们的服务器可能会经历CPU消耗100%的性能问题.
排除系统的异常,这类问题通常都是因为系统中存在性能低下甚至存在错误的SQL语句, 消耗了大量的CPU所致.
本文通过一个案例就如何捕获这样的SQL给出一个通用的方法.
问题描述:系统CPU高度消耗,系统运行缓慢
OS:Sun Solaris8
Oracle:Oracle9203
1.首先通过Top命令查看
$ top load averages: 1.61, 1.28, 1.25 HSWAPJSDB 10:50:44 172 processes: 160 sleeping, 1 running, 3 zombie, 6 stopped, 2 on cpu CPU states: % idle, % user, % kernel, % iowait, % swap Memory: 4.0G real, 1.4G free, 1.9G swap in use, 8.9G swap free PID USERNAME THR PR NCE SIZE RES STATE TIME FLTS CPU COMMAND 20521 oracle 1 40 0 1.8G 1.7G run 6:37 0 47.77% oracle 20845 oracle 1 40 0 1.8G 1.7G cpu02 0:41 0 40.98% oracle 20847 oracle 1 58 0 1.8G 1.7G sleep 0:00 0 0.84% oracle 20780 oracle 1 48 0 1.8G 1.7G sleep 0:02 0 0.83% oracle 15828 oracle 1 58 0 1.8G 1.7G sleep 0:58 0 0.53% oracle 20867 root 1 58 0 4384K 2560K sleep 0:00 0 0.29% sshd2 20493 oracle 1 58 0 1.8G 1.7G sleep 0:03 0 0.29% oracle 20887 oracle 1 48 0 1.8G 1.7G sleep 0:00 0 0.13% oracle 20851 oracle 1 58 0 1.8G 1.7G sleep 0:00 0 0.10% oracle 20483 oracle 1 48 0 1.8G 1.7G sleep 0:00 0 0.09% oracle 20875 oracle 1 45 0 1064K 896K sleep 0:00 0 0.07% sh 20794 oracle 1 58 0 1.8G 1.7G sleep 0:00 0 0.06% oracle 20842 jiankong 1 52 2 1224K 896K sleep 0:00 0 0.05% sadc 20888 oracle 1 55 0 1712K 1272K cpu00 0:00 0 0.05% top 19954 oracle 1 58 0 1.8G 1.7G sleep 84:25 0 0.04% oracle |
我们发现在进城列表里,存在两个高CPU耗用的Oracle进城,分别消耗了47.77%和40.98%的CPU资源.
2.找到存在问题的进程信息
$ ps -ef|grep 20521 oracle 20909 20875 0 10:50:53 pts/10 0:00 grep 20521 oracle 20521 1 47 10:43:59 ? 6:45 oraclejshs (LOCAL=NO) $ ps -ef|grep 20845 oracle 20845 1 44 10:50:00 ? 0:55 oraclejshs (LOCAL=NO) oracle 20918 20875 0 10:50:59 pts/10 0:00 grep 20845 |
确认这是两个远程连接的用户进程.
3.熟悉一下我的getsql.sql脚本
SELECT /*+ ORDERED */ sql_text FROM v$sqltext a WHERE (a.hash_value, a.address) IN ( SELECT DECODE (sql_hash_value, 0, prev_hash_value, sql_hash_value ), DECODE (sql_hash_value, 0, prev_sql_addr, sql_address) FROM v$session b WHERE b.paddr = (SELECT addr FROM v$process c WHERE c.spid = '&pid')) ORDER BY piece ASC / |
注意这里我们涉及了3个视图,并应用其关联进行数据获取.
首先需要输入一个pid,这个pid即process id,也就是在Top或ps中我们看到的PID.
通过pid和v$process.spid相关联我们可以获得Process的相关信息
进而通过v$process.addr和v$session.paddr相关联,我们就可以获得和session相关的所有信息.
再结合v$sqltext,我们即可获得当前session正在执行的SQL语句.
通过v$process视图,我们得以把操作系统和数据库关联了起来.
4.连接数据库,找到问题sql及进程
通过Top中我们观察到的PID,进而应用我的getsql脚本,我们得到以下结果输出.
$ sqlplus "/ as sysdba" SQL*Plus: Release 9.2.0.3.0 - Production on Mon Dec 29 10:52:14 2003 Copyright (c) 1982, 2002, Oracle Corporation. All rights reserved. Connected to: Oracle9i Enterprise Edition Release 9.2.0.3.0 - 64bit Production With the Partitioning, OLAP and Oracle Data Mining options JServer Release 9.2.0.3.0 - Production SQL> @getsql Enter value for spid: 20521 old 10: where c.spid = '&pid' new 10: where c.spid = '20521' SQL_TEXT ---------------------------------------------------------------- select * from (select VC2URL,VC2PVDID,VC2MOBILE,VC2ENCRYPTFLAG,S ERVICEID,VC2SUB_TYPE,CISORDER,NUMGUID,VC2KEY1, VC2NEEDDISORDER,V C2PACKFLAG,datopertime from hsv_2cpsync where datopertime<=sysda te and numguid>70000000000308 order by NUMGUid) where rownum<=20 |
那么这段代码就是当前正在疯狂消耗CPU的罪魁祸首.
接下来需要进行的工作就是找出这段代码的问题,看是否可以通过优化提高其效率,减少资源消耗.
5.进一步的我们可以通过dbms_system包跟踪该进程
SQL> @getsid SID SERIAL# USERNAME MACHINE SQL> exec dbms_system.set_sql_trace_in_session(45,38991,true); PL/SQL procedure successfully completed. SQL> !
|
我是如此得深爱着ssh
ssh 绝对不不仅仅是类似 telnet 这样远程登录管理管理服务器那么简单。下面的些 技巧,或许可以激发起你对这个“老朋友”重新认识的兴趣。
有部分内容来自:http://derwiki.tumblr.com/post/841579929/how-i-learned-to-stop-worrying-and-love-ssh
建立 HTTP 隧道
如果你需要访问线上集群中某台内网主机,那么你可以这样
ssh -f -N -L 31609:192.168.0.1:80 remotehost
当运行完毕以后,打开本地浏览器访问 http://localhost:31609 端口,则可以获取 remotehost 访问 192.168.0.1 的 80 端口的数据。
反向 ssh 隧道
如果本地局域网无法访问某些站点,那么你可以利用你的 ssh 主机通过它去访问。你可以使用
ssh -D 8080 remotehost
然后设置代理为 localhost:8080 则可以通过 remotehost 访问制定的资源。
PS,如果你使用 Mac,并经常会这样干,那么你会喜欢这个工具。
直接运行远程脚本
ssh 其实可以直接指定运行远程主机的命令。例如,每次登录并查看线上的日志是件非常繁琐的累活。其实你可以使用下面的命令
ssh user@remotehost "taif -f /var/log/apache/access.log"
它会 ssh 登录以后直接执行指定的命令。这样我们可以构建本地脚本让其接受远程服务器的输出,做更多的事情。
压缩传送文件或者目录
有时候不想开启 SFTP 工具传送文件,那么下面的命令会帮到你
tar cvfz - localFileOrDir | ssh user@remotehost 'cd /remote/path/to/unpack/ ; tar xvfz -'
这个命令可以自动讲本地的文件或者目录打包压缩以后,通过 ssh 传输到 remotehost 主机,然后 remotehost 会自动将其解压缩。
自动登录 ssh
最后个 ssh 技巧,上面的技巧的确是很实用,但是我们也受不了每次都要输入次密码。如果你的确厌烦了这些,那么尝试执行下面的命令:
ssh user@remotehost 'cat >> ~/.ssh/authorized_keys' < ~/.ssh/id_rsa.pub
这样远程的主机就会保存你本地的公钥,你就可以自动 ssh 登录远程主机。顺便提醒:强烈提醒您保护好您主目录下的 ssh 公钥,否则您的帐户可能会面临风险。
还有些有用的参数
- -C 这个参数可以将文本数据压缩传送
- -X 如果远程服务器支持 X11 forwarding ,那么远程的 X 应用直接可以在本地显示运行(当然你本地要有 X Server)
各位还有什么其它好用的 ssh tips,欢迎不吝指出。