前言 #
因为手头自己有三个服务器,所以想折腾一下负载均衡。
两个CentOS
,一个Ubuntu
,都是比较新的。
一开始准备用haproxy
来做负载均衡服务器,因为haproxy
相比与nginx
对cookie
和session
支持比较好,但是由于两个原因还是放弃了。
- 服务器被阿里云封掉
简单的在
haproxy
中设置后端服务器后,过一段时间就显示强制备案页面,由于我的域名没有备案。
后来我翻看了nginx
日志发现,haproxy
默认在request header
里面带了X-Host
,被阿里云发现了,这里提供一个解决方法
# 删除掉你header里面的 Host
# 在backend里面添加一句
http-request del-header Host
然而nginx
里面默认是没有添加Host
这个的,要你在localtion
中添加两句,如下面
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://main;
proxy_set_header Host www.example.com; # add Host
proxy_set_header X-Forwarded-For $remote_addr; # add X-Forwarded
}
}
- haproxy支持多开
我试了很多种选项,确定
pidfile
、改变uid
、gid
等等,haproxy
似乎可以允许很多个相同进程绑定同一个端口,虽然可以通过pid
来写一套类似service
管理的脚本,但终归很麻烦
我看网上有人写了这个脚本,但是nginx
自带了,还是用nginx
比较好,而且ansible
与service
的交互还不错。
nginx负载均衡 #
nginx负载均衡是通过反向代理来实现的,也就是把一台服务器的压力分摊到多台上面
要想实现这个必须要有后端服务器,假设我们有一台后端服务器1.1.1.1
,在代理主机的nginx
配置系统location
里面只要添加一条proxy_pass
就行了
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://1.1.1.1;
}
}
上面只是简单的实现了一个反向代理的功能,当你有一个后端服务群的时候,你就要使用负载均衡模块了,负载均衡模块在nginx
配置特别简单,添加一个upstream
模块,把服务器ip或者域名放到里面
upstream webservers{
server 1.1.1.1 weight=10;
server my.domain.com weight=10;
}
然后修改proxy_pass
后的为http://webservers
就行了
ps: nginx
对于后端反向代理服务器有个max_fails
和fail_timeout
属性,你要是设定了一个max_fails
次数,你代理服务器拿取失败了几次就会在fail_timeout
值之后尝试,和haproxy
的retry
属性差不多,但是似乎haproxy
的retry
不好使,我故意使用两个错误ip
和正确ip
,结果nginx
能一直正确返回正确ip
响应,而haproxy
有时候能,有时候不行。
nginx错误日志 #
在调试
nginx
碰到一些错误,记录一下如何系统的解决方法
- 调用
service nginx start
失败
首先看给的错误信息,假如让你看systemctl status nginx.service
或journalctl -xn
,输入去看
- 格式错误(format error)
一般你写的nginx
的配置文件有问题,这时候可以用nginx -t
检查格式,修改正确后会显示success
- 无法绑定地址(bind error)
一般是因为有别的应用程序占用端口造成的,这时候用netstat -tulpn
检查端口,然后选择kill
掉占用端口的程序或者换一个端口
ansible playbook 编写 #
具体代码可以参考nginx均衡负载ansible-playbook
首先你得写一个hosts
[ali]
my ansible_ssh_host=1.1.1.1 ansible_ssh_user=root
[tencent]
main ansible_ssh_host=1.1.1.2 ansible_ssh_user=root
[digital]
google ansible_ssh_host=1.1.1.3 ansible_ssh_user=root
前面[ ]
包着的是组名,最前面的my
和main
和google
是别名
,后面就是ip和用户名了。
写完hosts
后要写两个nginx
配置文件一个代理服务器的配置文件和一个后端服务器配置文件,playbook
很简单就是复制nginx
配置文件和重启nginx
。
---
- hosts: tencent
remote_user: root
tasks:
- name: copy nginx config file
template: src=~/test/lunge_proxy.conf dest=/etc/nginx/conf.d/lungelog.conf
notify: restart nginx
handlers:
- name: restart nginx
service: name=nginx state=restarted enabled=yes
解释一下notify
,在复制完成之后就启用一个handler
完成nginx
的重启,当然这里也可以使用reload
,假如在生产环境的话。
客户端和代理的playbook
差不多就不多介绍了。