nginx+tomcat负载均衡、session处理策略

来源:互联网 发布:软件图标 编辑:程序博客网 时间:2024/05/19 23:04

我先来说一下简单的配置nginx转发吧。

首先,把我们的tomcat项目配置三个,并行启动在本地。端口分别为:8080、8180、8280

然后,安装nginx,具体步骤如下:

下载链接
http://nginx.org/download/nginx-1.8.0.tar.gz

安装命令 ./cibfigure

安装pcre: yum -y install pcre pcre-devel
安装zlib: yum -y install zlib zlib-devel
./cibfigure
make
make install
验证是否安装成功:/usr/local/下有nginx文件夹
启动: /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
从容停止 kill -quit 进程号
查看ip端口: ps-ef grep nginx

配置文件在 安装目录/conf/nginx.conf
修改完后用/usr/local/nginx/sbin/nginx -s reload重新加载
负载均衡:
upstream colo {
server 127.0.0.1:8080;
server 127.0.0.1:8180;
server 127.0.0.1:8280;
}
location / {
#root html;
index index.html index.htm;
proxy_pass http://colo;
}
//路径错误解决
location / {
#root html;
#index index.html index.htm;
proxy_pass http://lib;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}

三台tomcat启动后,启动nginx。
当你访问你的web项目的时候,轮训到那台tomcat就有日志刷出来。说明成功。
现在,我使用apache ab性能测试工具进行测试。(jvm、tomcat三台全都一样)性能结果提升如下:

nginx+tomcat集群部署还是比较容易的,但是,对于集群项目,我们的登录信息平时是保存在session里面的,现在遇到了问题。三台机器轮询是不同的session。这时,我的选择是,把用户登录信息保存在redis中,并且带有一个独一无二的key(uuid),然后呢,这个uuid对应的保存到用户浏览器的cookie中。
控制层代码(springmvc)代码如下:
package controller;import java.util.UUID;import javax.servlet.http.Cookie;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import javax.servlet.http.HttpSession;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Controller;import org.springframework.ui.Model;import org.springframework.web.bind.annotation.CookieValue;import org.springframework.web.bind.annotation.RequestMapping;import entity.User;import redis.clients.jedis.Jedis;import service.UserService;import utils.RedisUtil;import utils.SerializeUtil;/** *  * @author Yu Yufeng * */@Controllerpublic class LoginController {@Autowiredprivate UserService userService;/** * 跳转到登录视图 *  * @param session * @param model * @return * @throws Exception */@RequestMapping("/login")public String loginUI(HttpSession session, Model model) throws Exception {return "login";}@RequestMapping("/quit")public String quit(HttpSession session, Model model, HttpServletResponse response,@CookieValue(value = "SESSIONUSER", required = false) String sessionUser) throws Exception {Cookie cookie = new Cookie("SESSIONUSER", null);Jedis jedis = RedisUtil.getJedis();jedis.del(sessionUser.getBytes());jedis.close();response.addCookie(cookie);return "redirect:login";}/** * 跳转到注册视图 *  * @param session * @param model * @return * @throws Exception */@RequestMapping("/register")public String registerUI(HttpSession session, Model model) throws Exception {return "register";}/** * 登录提交 *  * @param session * @param model * @return * @throws Exception */@RequestMapping("/login-sub")public String loginSubmit(HttpSession session, Model model, User user, HttpServletRequest request,HttpServletResponse response) throws Exception {if (userService.checkUserPwd(user)) {User record = userService.getUserByName(user.getUserName());String uuid = UUID.randomUUID().toString();Jedis jedis = RedisUtil.getJedis();jedis.setex(("user_"+uuid).getBytes(), 1800, SerializeUtil.serialize(record));jedis.close();Cookie cookie = new Cookie("SESSIONUSER", "user_"+uuid);response.addCookie(cookie);return "redirect:user/main";} else {model.addAttribute("message", "登录失败,用户名或密码错误!");return "login";}}@RequestMapping("/register-sub")public String registerSubmit(HttpSession session, Model model, User user) throws Exception {User record = null;try {record = userService.register(user);} catch (Exception e) {model.addAttribute("message", "用户名已存在");}if (null != record) {model.addAttribute("user", record);model.addAttribute("message", "注册成功");return "login";}return "register";}}

登录拦截:
package interceptor;import javax.servlet.http.Cookie;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.springframework.web.servlet.HandlerInterceptor;import org.springframework.web.servlet.ModelAndView;import entity.User;import redis.clients.jedis.Jedis;import utils.RedisUtil;import utils.SerializeUtil;/** * 测试拦截器 *  * @author yyf *  */public class UserInterceptor implements HandlerInterceptor {// 执行Handler完成执行此方法// 应用场景:统一异常处理,统一日志处理@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object object,Exception exception) throws Exception {}// 进入Handler方法之后,返回modelAndView之前执行// 应用场景从模型出发 公用model数据(菜单导航)在这里传到视图,也可以在这里统一指定视图@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object object,ModelAndView modelAndView) throws Exception {Cookie[] cs = request.getCookies();for (Cookie c : cs) {if (c.getName().equals("SESSIONUSER")) {Jedis jedis = null;if (c.getValue() != null && !"".equals(c.getValue())) {try {jedis = RedisUtil.getJedis();byte[] userb = jedis.get((c.getValue()).getBytes());User user = (User) SerializeUtil.unserialize(userb);request.setAttribute("session_user", user);String sCart = "cartNumber_" + c.getValue();String n = jedis.get(sCart);if (n != null) {request.setAttribute("cart_quantity", n);}} catch (Exception e) {e.printStackTrace();} finally {jedis.close();}}}}}// 进入Handler方法之前// 用于身份认真、身份授权@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object object) throws Exception {Cookie[] cs = request.getCookies();if (cs == null) {response.sendRedirect(request.getContextPath() + "/login");return false;}for (Cookie c : cs) {if (c.getName().equals("SESSIONUSER")) {if (c.getValue() != null && c.getValue() != null) {Jedis jedis = null;try {jedis = RedisUtil.getJedis();if (jedis.exists(c.getValue().getBytes())) {jedis.expire("cartNumber_" + c.getValue(), 1800);// 刷新redis时间jedis.expire("cart_" + c.getValue(), 1800);// 刷新redis时间jedis.expire(c.getValue(), 1800);// 刷新redis时间return true;} else {Cookie cook = new Cookie("SESSIONUSER", null);cook.setMaxAge(0);response.addCookie(cook);}} catch (Exception e) {e.printStackTrace();} finally {jedis.close();}}}}response.sendRedirect(request.getContextPath() + "/login");return false;}}

这样就实现了集群分布式项目用户登录信息的统一。
(这个策略曾经在我的某次作业中使用,现在拿出来分享以下这个策略。文章可能写的不是很好,,,但是自认为思想还是不错的大笑



1 0
原创粉丝点击