1、简介
html
最近新上了一个营销项目(和微信结合),后台用的是Tomcat。开始上线的时候由于人数很少感受没太多问题,随着正式环境的发布,开人有人反映服务器页面没法打开,连入tomcat查看时发现链接数已满且CPU也用到了极限,初始的架构以下图所示,其使用1台tomcat和一台数据库服务器。前端
该业务系统主要用于微信营销,顾客在微信上下单购买(抢)对应的商品,抢购成功后该商品(券)会自动生成条形码保存在该用户的注册信息中。用户凭券到实体店完成支付和取货操做。由于涉及券核销的问题(支付完成后即时核销),所以该业务没法放在云端(核销的数据和实体店销售数据需即时交互),最终只能经过本地的方案来解决。linux
首先考虑到的是将网上的链接经过负载均衡的方式分散来减轻服务器的压力,这方面可使用nginx代理来实现;其次须要解决的问题是session,对比了几种方案发现nginx内置的ip_hash策略能够解决该问题,最终网络的架构变成了下图所示,在该方案中增长了4台服务器,其中一台nginx负载转发,另外四台为新增的tomcat服务。nginx
2、安装Nginx数据库
Nginx的安装配置十分简单,我这里实际用的是tengine版本,具体的安装方法能够参考” nginx配置指南之一”。这里须要注意的是它的编译参数,记得它的配置文件和日志文件的存放位置。后端
3、优化系统资源缓存
文件限制tomcat
Linux系统中文件的打开个数及单用户最多拥有的进程数是有限制的,能够经过“ulimit -n”或“ulimit -u”来查看,详细的设置能够参考“ORACLE 11G在Linux下的标准安装方法(上)”。先修改/etc/security/limit.conf中的限制,以下图所示。安全
内核优化服务器
内核中涉及的TCP相关的选项在大并发链接的状况下也须要作相应的调整不然能够出“TCP: time wait bucket table overflow” 的错误提示。具体修改/etc/sysctl.conf文件,若有特殊要求请结合实际状况修改。具体以下所示:
tcp_max_tw_buckets 系统在同时所处理的最大 timewait sockets 数目。若是超过此数的话﹐time-waitsocket 会被当即删除而且显示警告信息。
ip_local_port_range 用于向外链接的端口范围。
netdev_max_backlog 每一个网络接口接收数据包的速率比内核处理这些包的速率快时,容许送到队列的数据包的最大数目,对重负载服务器而言,该值须要调高一点。
tcp_max_orphans 处理不属于任何进程的套接字数量,不属于任程进程的进程就是“孤儿(orphans)进程”,在快速、大量的链接中这种进程会不少所以要适当的设置该参数,也能够用来防护简单的DoS***。
tcp_max_syn_backlog 用于记录还没有收到客户端确认信息的链接请求的最大值。
4、优化Nginx
epoll为linux下的必须模型,适用于2.6之后的内核版本,以下图所示:
优化代理配置
须要注意的是“proxy_max_temp_file_size”,它主要用来设置临时文件的最大值。当被请求的文件内容大于代理缓存的大小时,该文件会被存储到这个临时文件,可是若是被请求文件的内容大于这个值的时候,那么将会从上游的服务器(被代理的服务器)上直接同步传递,而再也不使用代理缓存。该指令的默认值为1GB,若是设置为0,那么意味着禁止使用临时文件。
5、配置Nginx
Nginx配置以下所示,其中upstreambackend配置的是后端的tomcat应用,ip_hash表示启用该策略,用户的目的是为了解决后端session不一致的问题(在nginx前端还有CDN或是局域网的环境中须慎用)。
server段配置的是转发的路径和端口,须要注意“proxy_set_header Host $host:8162;”的写法。若是该变量后没有加8162端口则实际的转发会致使页面没法正常显示。其后的两条语句能够参考nginx日志的记录内容,主要用来记录外网实际的访问请求。($HOST 在使用80端口的时候ok,非80端口可使用$http_host。感谢ontheway2015指点)
log_format字段用来生成指定的日志格式文件,相应的变量对应日志文件中的访问记录,能够对照下图来查看。
6、Nginx安全限制
随着业务的增长,网络链接的流量愈来愈大,合理的控制访问请求及链接数很是重要,不然仍会出现失去响应的状况。
7、增长IP限制功能
最简单也最容易实现的的方式是Nginx自带的IP访问控制,由模块ngx_http_limit_conn_module和来ngx_http_limit_req_module实现,经过它们能够实现对IP地址链接数及服务器访问请求数的控制。
要限制链接,必须先有一个容器对链接进行计数,在http段加入以下代码:"zone=" 给它一个名字,能够随便叫,这个名字要跟下面的limit_conn 一致,$binary_remote_addr = 用二进制来储存客户端的地址,1m 能够储存 32000 个并发会话。
限制请求数的方式和限制链接数相似,其中“rate=10r/s”表示一秒中处理的请求为10个,若是须要限制为每分钟不超过30个则表示为“rate=30r/m”;一个具体的设定以下所示:
http { limit_req_zone$binary_remote_addr zone=one:10m rate=10r/s; limit_conn_zone$binary_remote_addr zone=two:10m; }
在server段中加入如下内容,其中“burst=5”表示同时容许超过频率限制的请求数很少于5个;“limit_conn two 15”表示对于同一IP的链接数限制为15个。
limit_req zone=one burst=5; limit_conn two 15;
后续WAF模块的添加以及nginx相关的监控待整理。