来源:网络
版权申明:内容来源网络,版权归原创者所有。除非无法确认,我们都会标明作者及出处,如有侵权烦请告知,我们会立即删除并表示歉意。谢谢!
往期惊喜:
SpringBoot+Vue+CAS 前后端分离实现单点登录方案
一次非常有意思的 SQL 优化经历:从 30248.271s 到 0.001s
扫码关注我们的Java架构师技术
带你全面深入Java
大家好,我是Java架构师
[root@caochenlei ~]# yum install -y gcc gcc-c++ make libtool wget pcre pcre-devel zlib zlib-devel openssl openssl-devel
[root@caochenlei ~]# tar -zxvf nginx-1.18.0.tar.gz
[root@caochenlei ~]# cd nginx-1.18.0
[root@caochenlei nginx-1.18.0]# ./configure
[root@caochenlei nginx-1.18.0]# make && make install
暴力停止服务:/usr/local/nginx/sbin/nginx -s stop
优雅停止服务:/usr/local/nginx/sbin/nginx -s quit
检查配置文件:/usr/local/nginx/sbin/nginx -t
重新加载配置:/usr/local/nginx/sbin/nginx -s reload
查看相关进程:ps -ef | grep nginx
[root@caochenlei ~]# /sbin/iptables -I INPUT -p tcp --dport 80 -j ACCEPT
[root@caochenlei ~]# /etc/rc.d/init.d/iptables save
iptables:将防火墙规则保存到 /etc/sysconfig/iptables:[确定]
#虚拟机域名 映射的网址
192.168.206.128 www.123.com
[root@caochenlei ~]# vi /usr/local/nginx/conf/nginx.conf
server {
listen 80;
server_name 192.168.206.128;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
proxy_pass http:127.0.0.1:8080;
root html;
index index.html index.htm;
}
[root@caochenlei ~]# /usr/local/nginx/sbin/nginx
[root@caochenlei ~]# wget https://mirror.bit.edu.cn/apache/tomcat/tomcat-7/v7.0.105/bin/apache-tomcat-7.0.105.tar.gz
[root@caochenlei ~]# tar -zxvf apache-tomcat-7.0.105.tar.gz
[root@caochenlei ~]# mv apache-tomcat-7.0.105 /usr/local/tomcat
[root@caochenlei ~]# /usr/local/tomcat/bin/startup.sh
[root@caochenlei ~]# /sbin/iptables -I INPUT -p tcp --dport 80 -j ACCEPT
[root@caochenlei ~]# /etc/rc.d/init.d/iptables save
[root@caochenlei ~]# /usr/local/tomcat/bin/shutdown.sh
[root@caochenlei ~]# /usr/local/nginx/sbin/nginx -s quit
[root@caochenlei ~]# /usr/local/tomcat/bin/shutdown.sh
[root@caochenlei ~]# vi /usr/local/nginx/conf/nginx.conf
server {
listen 80;
server_name 192.168.206.128;
#charset koi8-r;
#access_log logs/host.access.log main;
location ~ /edu/ {
proxy_pass http://127.0.0.1:8080;
}
location ~ /vod/ {
proxy_pass http://127.0.0.1:8081;
}
[root@caochenlei ~]# /usr/local/nginx/sbin/nginx
[root@caochenlei ~]# tar -zxvf apache-tomcat-7.0.105.tar.gz
[root@caochenlei ~]# mv apache-tomcat-7.0.105 /usr/local/tomcat1
[root@caochenlei ~]# tar -zxvf apache-tomcat-7.0.105.tar.gz
[root@caochenlei ~]# mv apache-tomcat-7.0.105 /usr/local/tomcat2
[root@caochenlei ~]# rm -f /usr/local/tomcat2/conf/server.xml
[root@caochenlei ~]# vi /usr/local/tomcat2/conf/server.xml
<?xml version='1.0' encoding='utf-8'?>
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<!-- Note: A "Server" is not itself a "Container", so you may not
define subcomponents such as "Valves" at this level.
Documentation at /docs/config/server.html
-->
<Server port="8006" shutdown="SHUTDOWN">
<Listener className="org.apache.catalina.startup.VersionLoggerListener" />
<!-- Security listener. Documentation at /docs/config/listeners.html
<Listener className="org.apache.catalina.security.SecurityListener" />
-->
<!--APR library loader. Documentation at /docs/apr.html -->
<Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
<!--Initialize Jasper prior to webapps are loaded. Documentation at /docs/jasper-howto.html -->
<Listener className="org.apache.catalina.core.JasperListener" />
<!-- Prevent memory leaks due to use of particular java/javax APIs-->
<Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
<Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
<Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />
<!-- Global JNDI resources
Documentation at /docs/jndi-resources-howto.html
-->
<GlobalNamingResources>
<!-- Editable user database that can also be used by
UserDatabaseRealm to authenticate users
-->
<Resource name="UserDatabase" auth="Container"
type="org.apache.catalina.UserDatabase"
description="User database that can be updated and saved"
factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
pathname="conf/tomcat-users.xml" />
</GlobalNamingResources>
<!-- A "Service" is a collection of one or more "Connectors" that share
a single "Container" Note: A "Service" is not itself a "Container",
so you may not define subcomponents such as "Valves" at this level.
Documentation at /docs/config/service.html
-->
<Service name="Catalina">
<!--The connectors can use a shared executor, you can define one or more named thread pools-->
<!--
<Executor name="tomcatThreadPool" namePrefix="catalina-exec-"
maxThreads="150" minSpareThreads="4"/>
-->
<!-- A "Connector" represents an endpoint by which requests are received
and responses are returned. Documentation at :
Java HTTP Connector: /docs/config/http.html (blocking & non-blocking)
Java AJP Connector: /docs/config/ajp.html
APR (HTTP/AJP) Connector: /docs/apr.html
Define a non-SSL HTTP/1.1 Connector on port 8080
-->
<Connector port="8081" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8444" />
<!-- A "Connector" using the shared thread pool-->
<!--
<Connector executor="tomcatThreadPool"
port="8081" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8444" />
-->
<!-- Define an SSL HTTP/1.1 Connector on port 8443
This connector uses the BIO implementation that requires the JSSE
style configuration. When using the APR/native implementation, the
OpenSSL style configuration is required as described in the APR/native
documentation -->
<!--
<Connector port="8444" protocol="org.apache.coyote.http11.Http11Protocol"
maxThreads="150" SSLEnabled="true" scheme="https" secure="true"
clientAuth="false" sslProtocol="TLS" />
-->
<!-- Define an AJP 1.3 Connector on port 8009 -->
<!--
<Connector protocol="AJP/1.3"
address="::1"
port="8010"
redirectPort="8444" />
-->
<!-- An Engine represents the entry point (within Catalina) that processes
every request. The Engine implementation for Tomcat stand alone
analyzes the HTTP headers included with the request, and passes them
on to the appropriate Host (virtual host).
Documentation at /docs/config/engine.html -->
<!-- You should set jvmRoute to support load-balancing via AJP ie :
<Engine name="Catalina" defaultHost="localhost" jvmRoute="jvm1">
-->
<Engine name="Catalina" defaultHost="localhost">
<!--For clustering, please take a look at documentation at:
/docs/cluster-howto.html (simple how to)
/docs/config/cluster.html (reference documentation) -->
<!--
<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>
-->
<!-- Use the LockOutRealm to prevent attempts to guess user passwords
via a brute-force attack -->
<Realm className="org.apache.catalina.realm.LockOutRealm">
<!-- This Realm uses the UserDatabase configured in the global JNDI
resources under the key "UserDatabase". Any edits
that are performed against this UserDatabase are immediately
available for use by the Realm. -->
<Realm className="org.apache.catalina.realm.UserDatabaseRealm"
resourceName="UserDatabase"/>
</Realm>
<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true">
<!-- SingleSignOn valve, share authentication between web applications
Documentation at: /docs/config/valve.html -->
<!--
<Valve className="org.apache.catalina.authenticator.SingleSignOn" />
-->
<!-- Access log processes all example.
Documentation at: /docs/config/valve.html
Note: The pattern used is equivalent to using pattern="common" -->
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
prefix="localhost_access_log." suffix=".txt"
pattern="%h %l %u %t "%r" %s %b" />
</Host>
</Engine>
</Service>
</Server>
[root@caochenlei ~]# /sbin/iptables -I INPUT -p tcp --dport 8081 -j ACCEPT
[root@caochenlei ~]# /etc/rc.d/init.d/iptables save
[root@caochenlei ~]# mkdir -p /usr/local/tomcat1/webapps/edu
[root@caochenlei ~]# echo "<h1>This is 8080 Port</h1>" > /usr/local/tomcat1/webapps/edu/a.html
[root@caochenlei ~]# mkdir -p /usr/local/tomcat2/webapps/vod
[root@caochenlei ~]# echo "<h1>This is 8081 Port</h1>" > /usr/local/tomcat2/webapps/vod/a.html
[root@caochenlei ~]# /usr/local/tomcat1/bin/startup.sh
[root@caochenlei ~]# /usr/local/tomcat2/bin/startup.sh
=:用于不含正则表达式的uri前,要求请求字符串与uri严格匹配,如果匹配成功,就停止继续向下搜索并立即处理该请求。
~:用于表示uri包含正则表达式,并且区分大小写。
~*:用于表示uri包含正则表达式,并且不区分大小写。
^~:用于不含正则表达式的uri前,要求Nginx服务器找到标识uri和请求字符串匹配度最高的location后,立即使用此location处理请求,而不再使用location块中的正则uri和请求字符串做匹配。
[root@caochenlei ~]# vi /usr/local/nginx/conf/nginx.conf
upstream myserver {
server 192.168.206.128:8080;
server 192.168.206.128:8081;
}
server {
listen 80;
server_name 192.168.206.128;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
proxy_pass http://myserver;
}
[root@caochenlei ~]# /usr/local/nginx/sbin/nginx
[root@caochenlei ~]# mkdir -p /usr/local/tomcat2/webapps/edu
[root@caochenlei ~]# echo "<h1>This is 8081 Port</h1>" > /usr/local/tomcat2/webapps/edu/a.html
[root@caochenlei ~]# /usr/local/tomcat1/bin/startup.sh
[root@caochenlei ~]# /usr/local/tomcat2/bin/startup.sh
[root@caochenlei ~]# /usr/local/nginx/sbin/nginx -s quit
[root@caochenlei ~]# /usr/local/tomcat1/bin/shutdown.sh
[root@caochenlei ~]# /usr/local/tomcat2/bin/shutdown.sh
[root@caochenlei ~]# mkdir -p /data/www/
[root@caochenlei ~]# mkdir -p /usr/local/tomcat/webapps/ROOT/www
[root@caochenlei ~]# echo "<h1>/data/www/a.html</h1>" > /data/www/a.html
[root@caochenlei ~]# echo "<h1>/usr/local/tomcat/webapps/ROOT/www/a.html</h1>" > /usr/local/tomcat/webapps/ROOT/www/a.html
[root@caochenlei ~]# vi /usr/local/nginx/conf/nginx.conf
server {
listen 80;
server_name 192.168.206.128;
#charset koi8-r;
#access_log logs/host.access.log main;
location /www/ {
root /data/;
index index.html index.htm;
}
[root@caochenlei ~]# /usr/local/nginx/sbin/nginx
[root@caochenlei ~]# /usr/local/tomcat/bin/startup.sh
[root@caochenlei ~]# /usr/local/nginx/sbin/nginx -s quit
[root@caochenlei ~]# /usr/local/tomcat/bin/shutdown.sh
[root@caochenlei ~]# vi /usr/local/nginx/conf/nginx.conf
upstream myserver {
server 192.168.206.128:8080;
server 192.168.206.128:8081;
}
server {
listen 80;
server_name 192.168.206.128;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
proxy_pass http://myserver;
}
[root@caochenlei ~]# /usr/local/nginx/sbin/nginx
[root@caochenlei ~]# /usr/local/tomcat1/bin/startup.sh
[root@caochenlei ~]# /usr/local/tomcat2/bin/startup.sh
[root@caochenlei ~]# yum install -y keepalived
[root@caochenlei ~]# rm -f /etc/keepalived/keepalived.conf
[root@caochenlei ~]# vi /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
notification_email {
acassen@firewall.loc
failover@firewall.loc
sysadmin@firewall.loc
}
notification_email_from Alexandre.Cassen@firewall.loc
#邮件服务器通知地址(暂不配置,默认即可)
smtp_server 192.168.200.1
#邮件服务器超时时间(暂不配置,默认即可)
smtp_connect_timeout 30
#当前虚拟机的IP地址
router_id 192.168.206.128
}
vrrp_script Monitor_Nginx {
script "/etc/keepalived/nginx_check.sh" #检测脚本执行的路径
interval 2 #检测脚本执行的间隔
weight 2 #检测脚本执行的权重
}
vrrp_instance VI_1 {
state MASTER #标识这个机器是MASTER还是BACKUP
interface eth0 #当前机器的网卡名称
virtual_router_id 51 #虚拟路由的编号,主备必须一致
priority 100 #主、备机取不同的优先级,主机值较大,备份机值较小
advert_int 1 #(VRRP Multicast广播周期秒数)
authentication {
auth_type PASS #(VRRP认证方式)
auth_pass 1111 #(密码)
}
track_script {
Monitor_Nginx #(调用Nginx进程检测脚本)
}
virtual_ipaddress {
192.168.206.50 #虚拟IP地址
}
}
[root@caochenlei ~]# vi /etc/keepalived/nginx_check.sh
#!/bin/bash
if [ "$(ps -ef | grep "nginx: master process" | grep -v grep )" == "" ]
then
killall keepalived
fi
[root@caochenlei ~]# service keepalived start
[root@caochenlei ~]# yum install -y gcc gcc-c++ make libtool wget pcre pcre-devel zlib zlib-devel openssl openssl-devel
[root@caochenlei ~]# wget http://nginx.org/download/nginx-1.18.0.tar.gz
[root@caochenlei ~]# tar -zxvf nginx-1.18.0.tar.gz
[root@caochenlei ~]# cd nginx-1.18.0
[root@caochenlei nginx-1.18.0]# ./configure
[root@caochenlei nginx-1.18.0]# make && make install
[root@caochenlei nginx-1.18.0]# cd ~
[root@caochenlei ~]# /sbin/iptables -I INPUT -p tcp --dport 80 -j ACCEPT
[root@caochenlei ~]# /etc/rc.d/init.d/iptables save
iptables:将防火墙规则保存到 /etc/sysconfig/iptables: [确定]
[root@caochenlei ~]# vi /usr/local/nginx/conf/nginx.conf
upstream myserver {
server 192.168.206.128:8080;
server 192.168.206.128:8081;
}
server {
listen 80;
server_name 192.168.206.128;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
proxy_pass http://myserver;
}
[root@caochenlei ~]# /usr/local/nginx/sbin/nginx
[root@caochenlei ~]# yum install -y keepalived
[root@caochenlei ~]# rm -f /etc/keepalived/keepalived.conf
[root@caochenlei ~]# vi /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
notification_email {
acassen@firewall.loc
failover@firewall.loc
sysadmin@firewall.loc
}
notification_email_from Alexandre.Cassen@firewall.loc
#邮件服务器通知地址(暂不配置,默认即可)
smtp_server 192.168.200.1
#邮件服务器超时时间(暂不配置,默认即可)
smtp_connect_timeout 30
#当前虚拟机的IP地址
router_id 192.168.206.129
}
vrrp_script Monitor_Nginx {
script "/etc/keepalived/nginx_check.sh" #检测脚本执行的路径
interval 2 #检测脚本执行的间隔
weight 2 #检测脚本执行的权重
}
vrrp_instance VI_1 {
state BACKUP #标识这个机器是MASTER还是BACKUP
interface eth1 #当前机器的网卡名称
virtual_router_id 51 #虚拟路由的编号,主备必须一致
priority 10 #主、备机取不同的优先级,主机值较大,备份机值较小
advert_int 1 #(VRRP Multicast广播周期秒数)
authentication {
auth_type PASS #(VRRP认证方式)
auth_pass 1111 #(密码)
}
track_script {
Monitor_Nginx #(调用Nginx进程检测脚本)
}
virtual_ipaddress {
192.168.206.50 #虚拟IP地址
}
}
[root@caochenlei ~]# service keepalived start
[root@caochenlei ~]# service keepalived stop
[root@caochenlei ~]# /usr/local/nginx/sbin/nginx -s quit
[root@caochenlei ~]# /usr/local/tomcat1/bin/shutdown.sh
[root@caochenlei ~]# /usr/local/tomcat2/bin/shutdown.sh
[root@caochenlei ~]# service keepalived stop
[root@caochenlei ~]# /usr/local/nginx/sbin/nginx -s quit
配置运行Nginx服务器用户(组)
worker process数
Nginx进程
PID存放路径错误日志的存放路径
一个Nginx进程打开的最多文件描述符数目
#配置worker进程运行用户(和用户组),nobody也是一个Linux用户,一般用于启动程序,没有密码
user nobody;
#user www www;
#配置工作进程数目,根据硬件调整,通常等于CPU数量或者2倍于CPU数量
worker_processes 1;
#配置全局错误日志及类型,[debug | info | notice | warn | error | crit],默认是error
error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#配置进程pid文件
pid logs/nginx.pid;
#一个nginx进程打开的最多文件描述符数目,理论值应该是最多打开文件数(系统的值ulimit -n)与Nginx进程数相除,但是Nginx分配请求并不均匀,所以建议与ulimit -n的值保持一致。
worker_rlimit_nofile 65535;
事件驱动模型的选择
最大连接数的配置
#参考事件模型,use [ kqueue | rtsig | epoll | /dev/poll | select | poll ];
#epoll模型是Linux 2.6以上版本内核中的高性能网络I/O模型,如果跑在FreeBSD上面,就用kqueue模型。
use epoll;
#单个进程最大连接数(最大连接数=连接数*进程数)
worker_connections 65535;
定义MIMI-Type
自定义服务日志
允许sendfile方式传输文件
连接超时时间
单连接请求数上限
#常见的一些基础配置
include mime.types; #文件扩展名与文件类型映射表
default_type application/octet-stream; #默认文件类型
charset utf-8; #默认编码
server_names_hash_bucket_size 128; #服务器名字的hash表大小
client_header_buffer_size 32k; #上传文件大小限制
large_client_header_buffers 4 64k; #设定请求缓冲
client_max_body_size 8m; #设定请求缓冲
sendfile on; #开启高效文件传输模式,对于普通应用设为on,如果用来进行下载等应用磁盘IO重负载应用,可设置为off,以平衡磁盘与网络I/O处理速度,降低系统的负载。注意:如果图片显示不正常把这个改成off。
autoindex on; #开启目录列表访问,合适下载服务器,默认关闭。
tcp_nopush on; #防止网络阻塞
tcp_nodelay on; #防止网络阻塞
keepalive_timeout 120; #长连接超时时间,单位是秒
#FastCGI相关参数是为了改善网站的性能:减少资源占用,提高访问速度。
fastcgi_connect_timeout 300;
fastcgi_send_timeout 300;
fastcgi_read_timeout 300;
fastcgi_buffer_size 64k;
fastcgi_buffers 4 64k;
fastcgi_busy_buffers_size 128k;
fastcgi_temp_file_write_size 128k;
#gzip模块设置
gzip on; #开启gzip压缩输出
gzip_min_length 1k; #最小压缩文件大小
gzip_buffers 4 16k; #压缩缓冲区
gzip_http_version 1.0; #压缩版本(默认1.1,前端如果是squid2.5请使用1.0)
gzip_comp_level 2; #压缩等级
gzip_types text/plain application/x-javascript text/css application/xml; #压缩类型
gzip_vary on; #增加响应头'Vary: Accept-Encoding'
limit_zone crawler $binary_remote_addr 10m; #开启限制IP连接数的时候需要使用
配置网络监听
配置https服务
基于名称的虚拟主机配置
基于IP的虚拟主机配置
#虚拟主机的常见配置
server {
listen 80; #配置监听端口
server_name localhost; #配置服务名
charset utf-8; #配置字符集
access_log logs/host.access.log main; #配置本虚拟主机的访问日志
location / {
root html; #root是配置服务器的默认网站根目录位置,默认为Nginx安装主目录下的html目录
index index.html index.htm; #配置首页文件的名称
}
error_page 404 /404.html; #配置404错误页面
error_page 500 502 503 504 /50x.html; #配置50x错误页面
}
#配置https服务,安全的网络传输协议,加密传输,端口443
server {
listen 443 ssl;
server_name localhost;
ssl_certificate cert.pem;
ssl_certificate_key cert.key;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
location / {
root html;
index index.html index.htm;
}
}
请求根目录配置更改
网站默认首页配置
location的URI
root html; #root是配置服务器的默认网站根目录位置,默认为Nginx安装主目录下的html目录
index index.html index.htm; #配置首页文件的名称
proxy_pass http://127.0.0.1:88; #反向代理的地址
proxy_redirect off; #是否开启重定向
#后端的Web服务器可以通过X-Forwarded-For获取用户真实IP
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
#以下是一些反向代理的配置,可选。
client_max_body_size 10m; #允许客户端请求的最大单文件字节数
client_body_buffer_size 128k; #缓冲区代理缓冲用户端请求的最大字节数,
proxy_connect_timeout 90; #nginx跟后端服务器连接超时时间(代理连接超时)
proxy_send_timeout 90; #后端服务器数据回传时间(代理发送超时)
proxy_read_timeout 90; #连接成功后,后端服务器响应时间(代理接收超时)
proxy_buffer_size 4k; #设置代理服务器(Nginx)保存用户头信息的缓冲区大小
proxy_buffers 4 32k; #proxy_buffers缓冲区,网页平均在32k以下的设置
proxy_busy_buffers_size 64k; #高负荷下缓冲大小(proxy_buffers*2)
proxy_temp_file_write_size 64k; #设定缓存文件夹大小
=:用于不含正则表达式的uri前,要求请求字符串与uri严格匹配,如果匹配成功,就停止继续向下搜索并立即处理该请求。
~:用于表示uri包含正则表达式,并且区分大小写。
~*:用于表示uri包含正则表达式,并且不区分大小写。
^~:用于不含正则表达式的uri前,要求Nginx服务器找到标识uri和请求字符串匹配度最高的location后,立即使用此location处理请求,而不再使用location块中的正则uri和请求字符串做匹配。
在 GitHub猿 还有更多优质项目系统学习资源,欢迎分享给其他同学吧!
最后,整理了300多套项目,赠送读者。扫码下方二维码,后台回复【赚钱】即可获取。
--END--
来源:网络
版权申明:内容来源网络,版权归原创者所有。除非无法确认,我们都会标明作者及出处,如有侵权烦请告知,我们会立即删除并表示歉意。谢谢!
往期惊喜:
SpringBoot+Vue+CAS 前后端分离实现单点登录方案
一次非常有意思的 SQL 优化经历:从 30248.271s 到 0.001s
扫码关注我们的Java架构师技术
带你全面深入Java