Nginx学习
一、概述
1.nginx是什么?
是一个高性能的反向代理服务器、还是一个负载均衡服务器
特点:在高并发和处理静态资源上相对于tomcat有更多优势.
-
什么是反向代理
-
正向代理:客户端发送请求到代理服务器,代理服务器将请求转发至原始服务器。代理服务器所代理的对象是很多个客户端。
-
反向代理:对于客户而言反向代理就像原始服务器,客户不需要作任何设置,客户端发送请求,直接发送到代理服务器,代理服务器判断向何处转发请求,并将获得的内容返回给客户端。反向代理是对多个服务器进行代理
-
-
什么是负载均衡
可以按照调度规则实现动态、静态页面分离,可以按照轮询、ip哈希、权重等多种方式实现将请求平均分配到后端服务器上
2.搭建服务器
-
网址:nginx.cn
四个软件下载方法:
1. wget ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-8.38.tar.gz 2. wget http://zlib.net/zlib-1.2.11.tar.gz 3. wget http://www.openssl.org/source/openssl-1.0.1j.tar.gz 4. wget http://nginx.org/download/nginx-1.11.1.tar.gz 5. yum -y install gcc-c++
-
安装pcre
-
安装c++编译器:yum -y install gcc-c++
-
创建目录:mkdir /opt/module/nginx
-
解压:tar -zxvf /opt/software/nginx/pcre-8.38.tar.gz -C /opt/module/nginx/
-
进入pcre目录,
./configure ,默认安装在/usr/lcal目录
-
make&&make install—安装到指定位置
-
-
openssl安装
-
tar -zxvf /opt/software/nginx/openssl-1.0.1j.tar.gz -C /opt/module/nginx/
-
进入openssl目录,
./config
-
make&&make install
-
-
zlib安装
- tar -zxvf /opt/software/nginx/zlib-1.2.11.tar.gz -C /opt/module/nginx/
- 进入zlib目录,./configure
- make&&make install
- nginx安装
- tar -zxvf /opt/software/nginx/nginx-1.11.1.tar.gz -C /opt/module/nginx/
- 进入nginx目录,./configure
- make&&make install,默认安装在/usr/local目录中
- 创建下面两个软链接
- ln -s /usr/local/lib/libpcre.so.1 /lib
- ln -s /usr/local/lib/libpcre.so.1 /lib64
- 启动服务:/usr/local/nginx/sbin目录中执行./nginx
- 测试:在浏览器输入虚拟机ip应该能看到欢迎界面
- 停止服务:./nginx -s stop
- 重启服务:./nginx -s reload
- 向服务器中传文件:alt+p–>进入sftp,cd到要传入的路径,如cd /opt/module/apache-tomcat-8.5.51/webapps/–>把文件直接拖入
二、配置文件
进入/usr/local/nginx/conf下,打开nginx.conf
##1.负载均衡
include mime.types;---包含文件,该文件中列出了nginx所支持的媒体类型
default_type application/octet-stream;---会让浏览器认为响应是普通文件流,并提示用户下载
keepalive_timeout 65;---处理完一次响应后,连接被保持的时间
server {
listen 8089;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
root html;
index index.html index.htm;
proxy_pass http://tc;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
upstream tc{
#ip_hash;
server 192.168.1.180:80 weight=1 backup;
server 192.168.1.180:8080 weight=3;
}
轮询:这是默认的策略,就是一个一个的按顺序提供服务.
weight:权重,对于静态资源,如html,jpg,在访问过后,nginx会缓存这些数据,再次访问时,会直接从nginx获取,不再访问服务器
backup:表示该服务器平时不用,其它服务器挂掉才启用,跟ip_hash会冲突
ip_hash:会根据用户的ip来决定由哪台服务器执行请求
启动linux的tomcat:./catalina.sh run
2.动静分离
2.1 什么是动静分离
让静态资源(image,html,js,css)跟动态资源分布在不同的服务器上,这种技术叫动静分离
2.2 实现步骤
-
在配置文件中添加
./指的是当前目录
location ~.*\.(html|js|png|css|jpg|gif) { root ./; }
-
在/usr/local/nginx目录中分别创建img目录,1.html文件放入html目录中,ng.gif图片放入img目录
-
创建两个springboot项目
-
导入依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency>
-
添加控制器类
@Controller public class NC { @RequestMapping("/test") @ResponseBody public String t1(){ return "负载均衡-----this is boot1"; } @RequestMapping("/showHtml") public String t2(){ return "show"; } }
-
两个端口号一个是80,一个是8080
-
在templates目录中添加show.html
<h1>动静分离</h1> <img src="img/ng.gif"><br> <a href="html/1.html">this is session1 html</a>
-
-
测试http://192.168.188.100/test
2.3可能遇到的问题
无法访问到资源:这边要使用重定向,而不能使用默认的或者转发跳转
/**
* 获取用户名与密码,用户登录
* @return 登录成功页面
*/
@RequestMapping(value = {"/userLogin"})
public String userLogin(@RequestParam("username") String username,
@RequestParam("password") String password,
HttpServletRequest request){
if(StringUtils.isEmpty(username)){
return "用户名不能为空";
}
if(StringUtils.isEmpty(password)){
return "密码不能为空";
}
User user = userLoginService.userLogin(username,password);
if(user != null){ //登录成功
request.getSession().setAttribute("session_user",user); //将用户信息放入session 用于后续的拦截器
return "redirect:product";
}
return "登录失败,用户名或密码错误";
}
@RequestMapping("/product")
public String toProduct(){
return "product";
}
三、session共享
什么是单点登录?单点登录全称Single Sign On(以下简称SSO),是指在多系统应用群中登录一个系统,便可在其他所有系统中得到授权而无需再次登录
1.ip_hash
缺点:
- 分配不均匀。
- 如果后端还作了其他负载均衡,就不能共享session
2.tomcat会话复制
会话数据会存储在每个服务器上的堆内存中
2.1 实现步骤
-
在每一个tomcat中添加集群缓存配置
在tomcat的conf中找到server.xml,在这一行下面添加下面内容:
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster" channelSendOptions="8"> <Manager className="org.apache.catalina.ha.session.DeltaManager" expireSessionsOnShutdown="false" notifyListenersOnReplication="true"/> <Channel className="org.apache.catalina.tribes.group.GroupChannel"> <Membership className="org.apache.catalina.tribes.membership.McastService" address="228.0.0.4" port="45564" frequency="500" dropTime="3000"/> <Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver" address="auto" port="4000" autoBind="100" selectorTimeout="5000" maxThreads="6"/> <Sender className="org.apache.catalina.tribes.transport.ReplicationTransmitter"> <Transport className="org.apache.catalina.tribes.transport.nio.PooledParallelSender"/> </Sender> <Interceptor className="org.apache.catalina.tribes.group.interceptors.TcpFailureDetector"/> <Interceptor className="org.apache.catalina.tribes.group.interceptors.MessageDispatch15Interceptor"/> </Channel> <Valve className="org.apache.catalina.ha.tcp.ReplicationValve" filter=""/> <Valve className="org.apache.catalina.ha.session.JvmRouteBinderValve"/> <Deployer className="org.apache.catalina.ha.deploy.FarmWarDeployer" tempDir="/tmp/war-temp/" deployDir="/tmp/war-deploy/" watchDir="/tmp/war-listen/" watchEnabled="false"/> <ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/> </Cluster>
-
在每个项目的web.xml中添加下面标签
<distributable/>
2.2 缺点
- 因为每个服务器都存储一份session,所以数据冗余
- 如果某个服务器内存很小,可能无法存储。
3.会话共享
推荐使用Spring Session方案,主流, 会话存储在远程的redis缓存中.
3.1 实现原理
-
客户端第一次发请求时,没有携带sessionID,nginx将请求分发给服务器1 ,然后服务器1 产生原始session,spring 对原始sesion封装成RedisSession,并对原始session的id进行base64编码产生一新id,新id作为key,RedisSession作为value, 放入redis中,然后原始session的ID回写到浏览器,这样服务器1 和redis中都会有一个相同的RedisSession
-
当客户端发送第二次请求的时候,nginx将请求分发给服务器2 (无session),因为请求中携带了一个sessionID,那么服务器2 就根据sessionID重新编码得出RedisSession的id,用这个id去redis中获取RedisSession[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kQcPz7cG-1634974473270)(picture\redis_session共享.png)]
-
面试题,封装的session对象所属的类叫什么?
参考DefaultCookieSerializer-->readCookieValues方法 封装的Session类型为HttpSessionAdapter,伪代码表示关系如下: HttpSessionAdapter //有属性如下 RedisSession session;
3.2 实现步骤
建两个springboot项目,内容如下,除了端口号不同
-
两个项目的pom依赖
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency> <groupId>org.springframework.session</groupId> <artifactId>spring-session-data-redis</artifactId> <version>2.0.4.RELEASE</version> </dependency> </dependencies>
-
templates目录添加login.html
<form action="/login" method="post"> <input name="username"><br> <input type="submit"> </form>
-
templates目录添加success.html
<html lang="en" xmlns:th="http://www.w3.org/1999/xhtml"> <h1>this is session1</h1> <span th:text="${session.username}"></span>
-
yml内容如下,注意:另一项目端口为8080
server: port: 80 spring: redis: host: 192.168.188.100 port: 6379 jedis: pool: max-idle: 8
-
config包下添加类
@Configuration public class MyConfig implements WebMvcConfigurer { public void addViewControllers(ViewControllerRegistry registry) { registry.addViewController("/showSuc").setViewName("success"); registry.addViewController("/showLogin").setViewName("login"); } }
-
controller包中添加类
@Controller public class UserCtl { @RequestMapping("/login") public String hello(HttpSession session, String username){ session.setAttribute("username",username); //注意:这里的session已不是传统session,被重构成新的session,存储在redis中 System.out.println("name:"+username+",sessionID:"+session.getId()); return "success"; } }
-
主类添加注解
//使用该注解,会重构session,参数为session存活时间,默认1800秒,注意:如果在30秒如果有访问,则过期时间会自动设置成30秒 @EnableRedisHttpSession(maxInactiveIntervalInSeconds = 30) @SpringBootApplication public class SessionApp { public static void main(String[] args) { SpringApplication.run(SessionApp.class,args); } }
-
nginx中
-
修改配置
upstream tc{ server 192.168.1.144:80; server 192.168.1.144:8080; }
-
重启nginx
/usr/local/nginx/sbin/nginx -s reload
-
-
启动redis: redis-server redis.conf
-
启动80和8080两个端口的项目
-
测试
-
浏览器输入192.168.188.100/showLogin,输入用户名
-
192.168.188.100/showSuc,反复刷新观看
-
posted on 2021-10-23 15:37 JavaCoderPan 阅读(5) 评论(0) 编辑 收藏 举报 来源