前言 #
因为手头自己有三个服务器,所以想折腾一下负载均衡。
两个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差不多就不多介绍了。