openssl genrsa -des3 -out 《证书名称》.key 2048
openssl rsa -in test.key -out 《要生成的无密码私钥名称》.key
openssl req -new -key 《私钥名称》.key -out 《要生成的签名文件名称》.csr
openssl x509 -req -days 365 -in 《签名文件名称》.csr -signkey 《私钥名称》.key -out 《要生成的证书名称》.crt
server {
#端口后边+ ssl 意思是开启ssl支持https
listen 10086 ssl;
server_name <项目名称要和生成私钥的compony对应上才可>;
#SSL配置
ssl_certificate /ssl/test.crt; # 配置证书地址
ssl_certificate_key /ssl/test_nopass.key; # 配置证书私钥地址
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # 配置SSL协议版本
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE; # 配置SSL加密算法
ssl_prefer_server_ciphers on; # 优先采取服务器算法
ssl_session_cache shared:SSL:10m; # 配置共享会话缓存大小
ssl_session_timeout 10m; # 配置会话超时时间
charset utf-8;
location / {
proxy_pass https://webgroup;
# 如下的配置很重要不然会发现有些前后端未分离的项目页面请求路径前缀会变成proxy_pass
proxy_redirect off;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log notice;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
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 /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
include /etc/nginx/conf.d/*.conf;
upstream webgroup{
ip_hash;
server 10.36.6.20:81 weight=1;
server 10.36.6.20:82 weight=1;
}
#端口后边+ ssl 意思是开启ssl支持https
listen 10086 ssl;
server_name <项目名称要和生成私钥的compony对应上才可>;
#SSL配置
ssl_certificate /ssl/test.crt; # 配置证书地址
ssl_certificate_key /ssl/test_nopass.key; # 配置证书私钥地址
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # 配置SSL协议版本
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE; # 配置SSL加密算法
ssl_prefer_server_ciphers on; # 优先采取服务器算法
ssl_session_cache shared:SSL:10m; # 配置共享会话缓存大小
ssl_session_timeout 10m; # 配置会话超时时间
charset utf-8;
location / {
proxy_pass https://webgroup;
# 如下的配置很重要不然会发现有些前后端未分离的项目页面请求路径前缀会变成proxy_pass
proxy_redirect off;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
# nginx ---------------------------------------------
nginx:
labels:
service: nginx
logging:
options:
labels: "service"
restart: always
image: nginx
container_name: nginx
ports:
- 8080:80
- 80:1080
volumes:
- /nginx/nginx.conf:/etc/nginx/nginx.conf
- /nginx/log:/var/log/nginx
- /ssl:/ssl
networks:
- soil-net
environment:
- TZ=Asia/Shanghai
前言: 这里使用的阿里的数据库连接池druid,灵感来自于他的主从分离,我一想你可以主从分离那肯定是哪里可以该数据库的url地址啊,然后我一行一行debug终于找到了一个办法可以改,但是这样只是个临时凑合的办法会慢,我的服务切换会有五六秒的时间才可以切换过来,再此建议增加中间件keepalive+双主备份的情况让服务和mysql解耦
@ControllerAdvice(value = "要拦截的目录例如com.test.controller")
@Slf4j
public class DefaultGlobalExceptionHandlerAdvice {
/**
* 数据库连接超时
*
* @param ex
* @return
*/
@ResponseBody
@ExceptionHandler(RecoverableDataAccessException.class)
public ReturnMsg dataAccessResourceFailureException(RecoverableDataAccessException ex) {
//发生异常切换数据源
CustomizeDruidDataSource.switchDbType();
return "系统异常!";
}
}
前言: 我还做了读写分离的一些工作,但没必要展示,这里的urls可以自己往里边传,我是有个配置文件自己拼装了一个数组放进来的
import com.alibaba.druid.pool.DruidDataSource;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
/**
* @explain 替换掉alibaba数据源类,动态切换数据库,一旦数据库挂掉切换到另一台
* @Classname CustomizeDruidDataSource
* @Date 2021/10/11 12:20
* @Created by hanzhao
*/
public class CustomizeDruidDataSource extends DruidDataSource {
private boolean lastInited;
private static boolean dbStatus = true; //true代表主库运行正常,false代表主库运行异常
private String[] urls;
public static void switchDbType() {
if(dbStatus){
dbStatus = false;
}else{
dbStatus = true;
}
}
public String[] getUrls() {
return urls;
}
public void setUrls(String[] urls) {
this.urls = urls;
}
@Override
public void init() throws SQLException {
lastInited = inited;
super.init();
if (!lastInited && inited) {
new Thread(new ValidateUrlTask()).start();
}
}
class ValidateUrlTask implements Runnable {
@Override
public void run() {
while (true) {
// 如果这个数据源被关闭了,就结束这个定时任务
if (isClosed()) {
break;
}
//如果这个数据源已经被初始化了,同时连接异常才进行处理
if (isInited() && !dbStatus) {
for (String thisUrl : urls) {
Connection connection = null;
try {
connection = DriverManager.getConnection(thisUrl, username, password);
jdbcUrl = thisUrl;
CustomizeDruidDataSource.switchDbType();
} catch (Exception ignored) {
} finally {
try {
connection.close();
} catch (Exception ignored) {
}
}
}
}
try {
Thread.sleep(1000);
} catch (InterruptedException ignored) {
}
}
}
}
}
spring:
#数据源地址
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driverClassName: com.mysql.cj.jdbc.Driver
druid:
# 主库数据源
master:
url: jdbc:mysql://url?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&useSSL=true
username: root
password: 密码
# 从库数据源
slave:
#从数据源开关/默认关闭
enabled: true
url: jdbc:mysql://url?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&useSSL=true
username: root
password: 密码
# 初始连接数
initialSize: 5
# 最小连接池数量
minIdle: 10
# 最大连接池数量
maxActive: 20
# 配置获取连接等待超时的时间
maxWait: 60000
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
timeBetweenEvictionRunsMillis: 60000
# 配置一个连接在池中最小生存的时间,单位是毫秒
minEvictableIdleTimeMillis: 300000
# 配置一个连接在池中最大生存的时间,单位是毫秒
maxEvictableIdleTimeMillis: 900000
# 配置检测连接是否有效
validationQuery: SELECT 1 FROM DUAL
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
webStatFilter:
enabled: true
statViewServlet:
enabled: true
# 设置白名单,不填则允许所有访问
allow:
url-pattern: /monitor/druid/*
filter:
stat:
enabled: true
# 慢SQL记录
log-slow-sql: true
slow-sql-millis: 1000
merge-sql: true
wall:
config:
multi-statement-allow: true
[mysqld]
# [必须]服务器唯一ID,默认是1,一般取IP最后一段
server-id=1
# [必须]启用二进制日志
log-bin=mysql-bin
# 复制过滤:也就是指定哪个数据库不用同步(mysql库一般不同步)
binlog-ignore-db=mysql
# 数据目录
datadir = /var/lib/mysql
# 错误日志位置
log-error = /var/log/mysql/error.log
# 设置需要同步的数据库 binlog_do_db = 数据库名;
# 如果是多个同步库,就以此格式另写几行即可。
# 如果不指明对某个具体库同步,表示同步所有库。除了binlog-ignore-db设置的忽略的库
# binlog_do_db = test #需要同步test数据库。
# 确保binlog日志写入后与硬盘同步
sync_binlog = 1
# 跳过所有的错误,继续执行复制操作
slave-skip-errors = all
sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
soilmysql_master:
labels:
service: soilmysql_master
logging:
options:
labels: "service"
user: "root"
restart: always
image: mysql:5.7
container_name: "mysql_master"
ports:
- "10086:3306"
volumes:
- 《将数据库日志数据等信息存储到宿主的磁盘中》:/var/lib/mysql
- 《宿主mysql配置文件路径》:/etc/mysql/mysql.conf.d/mysqld.cnf
environment:
MYSQL_ROOT_PASSWORD: 初始root账户密码
networks:
- soil-net
soilmysql_slave:
labels:
service: mysql_slave
logging:
options:
labels: "service"
user: "root"
restart: always
image: mysql:5.7
container_name: "soilmysql_slave"
ports:
- "10010:3306"
volumes:
- 《将数据库日志数据等信息存储到宿主的磁盘中》:/var/lib/mysql
- 《宿主mysql配置文件路径》:/etc/mysql/mysql.conf.d/mysqld.cnf
environment:
MYSQL_ROOT_PASSWORD: 初始root账户密码
networks:
- soil-net
http://nginx.org/en/
https://www.nginx.cn/doc/
https://www.jianshu.com/p/06952c316f0c
https://www.runoob.com/w3cnote/nginx-setup-intro.html
https://blog.csdn.net/u011659193/article/details/85778764
https://blog.csdn.net/zhenghongcs/article/details/109302331
https://www.cnblogs.com/a1304908180/p/10351930.html
https://blog.csdn.net/zhangguanghui002/article/details/78959816
https://www.jianshu.com/p/70ca1ef79cd4
https://help.aliyun.com/knowledge_detail/41106.html?spm=a2c6h.13066369.0.0.5ae84055BKlrw9#XACzT