使用命令 nginx -vhtml
一个在本身机器上(192.168.1.120),一个在测试服务器(192.168.8.110)上。服务端口均为1008。java
调用rest服务时向一张表nginx_test中写入数据。nginx
访问url:web
/nginxTest/insert(接口添加到不用作验证的接口列表)redis
192.168.1.120服务上实例向数据库表写入字段666spring
192.168.8.110服务上实例向数据库写入字段8.110sql
#user nobody; worker_processes 1; #error_log logs/error.log; #error_log logs/error.log notice; #error_log logs/error.log info; #pid logs/nginx.pid; events { worker_connections 1024; } http { include mime.types; default_type application/x-www-form-urlencoded; #log_format main '$remote_addr - $remote_user [$time_local] "$request" ' # '$status $body_bytes_sent "$http_referer" ' # '"$http_user_agent" "$http_x_forwarded_for"'; #access_log logs/access.log main; error_log logs/access.log info; sendfile on; #tcp_nopush on; #keepalive_timeout 0; keepalive_timeout 65; #gzip on; upstream tomcats { server 192.168.1.120:1008 weight=1; server 192.168.8.110:1008 weight=2; } server { listen 80; location / { proxy_pass http://tomcats; } } }
SET FOREIGN_KEY_CHECKS=0; -- ---------------------------- -- Table structure for nginx_test -- ---------------------------- DROP TABLE IF EXISTS `nginx_test`; CREATE TABLE `nginx_test` ( `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, `ip` varchar(20) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=28 DEFAULT CHARSET=utf8;
package com.richfit.ruiche.nginxTest.controller; import javax.servlet.http.HttpServletRequest; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import com.richfit.ruiche.nginxTest.service.NginxTestService; @RestController @RequestMapping(value = "/nginxTest") public class NginxTestController { private static final String ip = "666"; // private static final String ip = "8.110"; @Autowired private NginxTestService nginxTestService; @RequestMapping(value = "/insert") public void insert(HttpServletRequest request) throws NoSuchMethodException, SecurityException{ nginxTestService.insert(ip); } }
package com.richfit.ruiche.nginxTest.service; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.richfit.ruiche.nginxTest.mapper.NginxTestMapper; @Service public class NginxTestService { @Autowired private NginxTestMapper nginxTestMapper; public void insert(String ip){ nginxTestMapper.insert(ip); } }
package com.richfit.ruiche.nginxTest.mapper; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; @Mapper public interface NginxTestMapper { void insert(@Param(value="ip")String ip); }
<?xml version = "1.0" encoding = "UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD com.example.Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace = "com.richfit.ruiche.nginxTest.mapper.NginxTestMapper"> <insert id="insert" parameterType="string"> <![CDATA[ INSERT INTO nginx_test ( ip ) VALUES ( #{ip} ) ]]> </insert> </mapper>
配置文件为nginx.conf,位置以下数据库
直接访问nginx服务器的地址(由于nginx配置的是80端口,因此这里没写):apache
http://localhost/nginxTest/insertwindows
配置文件的关键部分写成以下这样:
upstream tomcats { server 192.168.1.120:1008; server 192.168.8.110:1008; } server { listen 80; location / { proxy_pass http://tomcats; } }
那么默认就是按轮询的方式进行的,先服务器1,再服务器2,再服务器1,依次轮询。。。
关闭192.168.1.120服务器(即本机),那么发现服务都转发到了192.168.8.110了。可见nginx很强大。
upstream tomcats { server 192.168.1.120:1008 weight=1; server 192.168.8.110:1008 weight=2; } server { listen 80; location / { proxy_pass http://tomcats; } }
如上weight就是权重。如上配置的话,就会访问1次192.168.1.120,而后访问2次192.168.8.110,而后访问1次192.168.1.120,而后访问2次192.168.8.110。。。
实际中访问的是server,
可是server只是个代理,将请求转发给了服务器组。具体的访问策略,则根据nginx的规则本身选择。
一、轮询
轮询即Round Robin,根据Nginx配置文件中的顺序,依次把客户端的Web请求分发到不一样的后端服务器上。若是后端服务器down掉,能自动剔除。
二、最少链接 least_conn;
Web请求会被转发到链接数最少的服务器上。
三、IP地址哈希 ip_hash;
每一个请求按访问ip的hash结果分配,这样每一个访客固定访问一个后端服务器,能够解决session的问题。
四、基于权重 weight
指定轮询概率,weight和访问比率成正比,用于后端服务器性能不均的状况。
upstream tomcats { server 192.168.1.120:1008 weight=1; server 192.168.8.110:1008 weight=2; } server { listen 80; location / { proxy_pass http://tomcats; } }
proxy_pass http://tomcats:表示将全部请求转发到tomcats服务器组中配置的某一台服务器上。tomcats是服务器组的名称。
upstream模块:配置反向代理服务器组,Nginx会根据配置,将请求分发给组里的某一台服务器。tomcats是服务器组的名称。
upstream模块下的server指令:配置处理请求的服务器IP或域名,端口可选,不配置默认使用80端口。
可用性提升:运行多个服务实例,好比两个,因为机器故障一个down时,服务整体仍可用。
性能提升:提升并发访问数量。
我系统中没有使用session。
我在系统中使用的不是session,而是在token中夹带了不少信息。如何判断用户是否掉线了呢?
用户首次登陆成功时,用redis或者guava缓存新增LoginMap<Long userId,DataTime loginTime>。
有个定时任务定时扫描LoginMap,若上次访问时间loginTime超过设置时间(好比1个小时),则将该key-value踢出LoginMap。
后面每次访问根据userId先查看LoginMap是否存在值,若存在直接可进入系统并刷新 loginTime;若不存在则须要从新登陆。
使用redis或者guava存储LoginMap<Long userId,DataTime loginTime>都可。
此时使用guava不能够了。由于guava是跟随服务实例的,不是全局的,确定会形成混乱。
此时使用redis便可,无论几个服务实例,都使用redis存储LoginMap<Long userId,DataTime loginTime>。由于redis是全局的,全部服务实例共享redis,跟单机其实是同样的。
实现负载均衡经常使用的Web服务器软件有Nginx、HAProxy、LVS、Apache。