项目中使用总结
Nginx
- 
反向代理 #反向代理
 server {
 #监听端口
 listen 90;
 
 location /{
 #跨域问题
 add_header 'Access-Control-Allow-Origin' '$http_origin';
 add_header 'Access-Control-Allow-Credentials' 'true';
 add_header 'Access-Control-Allow-Methods' 'POST, GET, OPTIONS, DELETE, PUT';
 add_header 'Access-Control-Allow-Headers' 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
 
 #跨域OPTIONS请求,set response header后直接204返回
 if ($request_method = 'OPTIONS') {
 return 204;
 }
 
 proxy_set_header X-Real-IP $remote_addr;
 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
 #代理的地址(此处代理的是负载均衡的两个地址)
 proxy_pass http://test;
 }
 }- 
负载均衡 - 
轮询(默认) 
- 
权重自己设置(weight) 
- 
ip_hash(访问ip跟服务器绑定) 
 
- 
 #负载均衡
 upstream test {
 #权重数字越大接收请求越多
 server localhost:8081 weight=9;
 #ip_hash
 ip_hash
 server localhost:8082;
 }
- 
- 
静态服务器搭建 
   server {
         #监听端口
         listen   8888;
         location / {
             #本地存放的位置
             root E:/static_server/img;
             autoindex on;
         }  
     } 
- 
静态资源的部署 
将前端打包部署到html文件夹下
Redis
redis查询时是一个单线程的,持久化时,开启的时多线程。多线程中有3种方案:同步阻塞IO、同步非阻塞IO、异步非阻塞IO
redis集群搭建 1.主从同步:一主一从 数据一致(高可用) 2.主从分离:一主两从 数据存在不同redis中 3.集群搭建:3主3从:使用哨兵模式,进行主节点选举
 Redis五种数据存储类型
 Sting(字符串)
 Hash(对象)
 List(可重复集合)
 Set(无序、不可重复)
 Zset(有序、去重)
- 
导包 
- 
配置 
 #端口号
 Spring.redis.prot=6379
 #服务器
 Spring.redis.host=
- 
使用 
- 
缓存同步 
当数据库修改后怎么同步redis
1.修改数据库时首先判断redis中是否有该值对应的key如果有的直接删除key
2.修改数据库时同时修改redis中的数据
- 
缓存穿透 
当用户使用数据库不存在的key进行访问时,会穿过redis直接访问数据库
1.给这个key设置null值 并设置定时
- 
缓存击穿 
当redis中的key被高并发请求访问时 该key突然失效 请求会全部访问到数据库 造成数据库压力增大
1.可以设置key永不失效
- 
缓存雪崩 
和缓存击穿相差不大 雪崩是大量key失效
1.设置加长失效时间
2.避免缓存同一时间失效
- 
redis持久化 - 
AOF 
 持续的日志添加,操作一次redis就会记录一次日志 - 
RDB 
 快照,每30秒,对当前redis中的内存进行保存记录到磁盘中 
- 
支付宝支付
- 
导包 
    <dependency>
             <groupId>com.alipay.sdk</groupId>
             <artifactId>alipay-sdk-java</artifactId>
             <version>4.22.57.ALL</version>
         </dependency>
- 
配置 
 alipay:
   #支付宝appid
   appid: 2021000119603005
   #公钥
   publickey: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAhj/8JJXO9tXArnzvUr2gqSqO+o4pnGeZUumhnsbF5gl8dwp6MlxpZO2VHwhnzte/lQXH8hsGS8WotUypbaqaks7S6GHmMgcoseTeq8kPbAIu8SCmlO/tPG8XCGWWqcr2IKuFUdzLgx9UDphtbLCFr6Pm76N2OTHFMcsvJHyBY+GEQbnP050mmH+39ft19F49vWzC7BAzlHWI4g2+KNgPCBlrgrhbcd1ydofJEIAj7UGvV8DwtlIg27Dmw58F4NW3CDtDIAsqT1TPIiFSjNo+VTrXE4IMSZm7a/oZIXdB8rKrXh7O1zd7zmfFeVhwftCqJ/MeDX0/0750ckmX5bTmNQIDAQAB
   #私钥
   securitykey: MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCGP/wklc721cCufO9SvaCpKo76jimcZ5lS6aGexsXmCXx3CnoyXGlk7ZUfCGfO17+VBcfyGwZLxai1TKltqpqSztLoYeYyByix5N6ryQ9sAi7xIKaU7+08bxcIZZapyvYgq4VR3MuDH1QOmG1ssIWvo+bvo3Y5McUxyy8kfIFj4YRBuc/TnSaYf7f1+3X0Xj29bMLsEDOUdYjiDb4o2A8IGWuCuFtx3XJ2h8kQgCPtQa9XwPC2UiDbsObDnwXg1bcIO0MgCypPVM8iIVKM2j5VOtcTggxJmbtr+hkhd0HysqteHs7XN3vOZ8V5WHB+0Kon8x4NfT/TvnRySZfltOY1AgMBAAECggEAU1kGQfCAPd8XcT0/mC8CwAQcIJKCYwguuLs0DE98LgVVsNJga0PUa0TVgB7H1DM+Tlb4e+crUX+17llaFywEK4EckAm30PeA3HErjZuWZ4gzfKC4y17p+ss9kYkAsQnBJSdX7isWbqHUnfskdIZjeVhY2A60J24u72smKZDjBA7naVUZ5jo+X6N1IsjuBisQCuiBH5OyG3KlTae5F+eU2x/xkC4I5NadzdgkEmt6CoaBsU1bLrmn8ygnJeA5tt/ef8YBFWcSXDFSaCzpaNvuWCVXFe4RsQ+VkkfEhDQrdZdK62O+t62OSw6gJMGmnVCD12IlIhM4H2ewL14t0q3lQQKBgQDO36rNFzVWynXhQXyS1RCTXqoyZmU3lHPAIlauvabLaqvCs4BmXnhElds6wzzsM0gMnArFjzjOMKy5dcJrPKtk2yLt4KlNaCpYXFz50+j3VMV1f6D4nLYX8cFhi83dexPjhoIRqZ00IwcReQyQ4kLs0IjRi5aHrYG2GEOpOYrRHwKBgQCmIVnJfCcnUwKPfj9cO27ynNGW0DuiaRMx8hFrB4bAhwy8iima9Zm2J5uhqhTutDvMdifYbYlTMQFk4rQ9E1f9neqGAAKurPTRAy3WUgaS4VQqVyTHX8TkmSS987tqCxUQGvfHxvG5K1jHz8NLoqZLoxSNHCxrHxdMJjBuneV6KwKBgBm/kwW11si3qFZiDTxFUqvVA4AEaKKzUnjejUVwi3sUCs7QArI7HeMDd+bneAS6GUSgg2K1gc+AFW977bflNDv4Xm+XH9tnlKWs0VGzA3MNVQpb2VA4SR3P1E7s1LG1aPNPwY6rOsrLdUzCcULzNns9NVpHcnPur49Xk8xTQijnAoGBAJiDQ49yV+uFDHO5PeepdFhsWQkwD58xAXs3tH/if/XdxXaNDFcDI+MTB5BpuR/O/Jre2gOZw5lJAvOgIEF1sbDWOYhdGBlOFM6RMZJw6TIMhJz+NXiHVhVa9l0gFazrkaGgcFrKK/2HatC8zphwMGR9yY8mDy0kdNnmsU3LzPDTAoGAVi37NXztwq+orACzS9tVvGExRCeMHZW/2Y8uUZMtz153vMWFOO5NcQpDXpvROBHKoCRJxDTeV5g2ZTwqrC4CUNqX0IMjW/agX/B0SqSqBtplR72VOOd+Q9fSip4imAnKlmYBJTodbYn6Xl8p7/C95QR9aBr4HwAhlbsVDS9FUpo=
   #支付宝公钥
   alipaypublickey: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAh71b3Xa142+fdvEZL6klvehRuV8Tj1q6nzKI90XafhkCb0pCq/Lxj8UBchsglaDgfKp/MGe4gUZahUQYs6NZCcCkf/CL0uN87u85OebVW/J0UNSUroXNzqsLKchPTLCzsdC+NQL7D4BAljDNDdq14DFbR5oOpsKrY6SJz8zsVQG9/mC620Pq0Gj0bW3+lgh6y4HQnFIPwLQ2wzNIUtjBFiNBWa3IjgOXPGQHqNHcnPk95d9m5hZxK900tCB9T6ll7SgEnltNVLYZORYCHVJ74yyHv/FyhRrvPXcs3xVQLqBBpvsxrt9oc+mJf2VqeDB+foY+0F/tOg29Mgd6zSDPpQIDAQAB
   #异步回调的地址,后端接口的地址
   notifyUrl: http://pc38k4.natappfree.cc/pay/callback
   #同步回调的地址,前端页面的地址
   returnUrl: http://localhost:8081/#/orderinfo
   #支付宝网关
   serverUrl: https://openapi.alipaydev.com/gateway.do
- 
使用(工具类) 
 流程:1.将订单传入支付(pay)方法 同时修改订单状态为正在支付
     2.在回调函数中执行验签(callback)方法,验签完毕执行逻辑将订单状态修改为已支付
 //将订单传入支付
 
     //从配置文件中获取值
     @Value("${alipay.appid}")
     private String appid;
     @Value("${alipay.publickey}")
     private String publickey;
     @Value("${alipay.securitykey}")
     private String securitykey;
     @Value("${alipay.alipaypublickey}")
     private String alipaypublickey;
     @Value("${alipay.notifyUrl}")
     private String notifyUrl;
     @Value("${alipay.returnUrl}")
     private String returnUrl;
     @Value("${alipay.serverUrl}")
     private String serverUrl;
     private static Logger logger = LoggerFactory.getLogger(AlipayUtils.class);
 
 
 
 
 public String pay(QfOrder order){
         AlipayClient alipayClient =  new DefaultAlipayClient( serverUrl , appid, securitykey, "json", "         utf-8", alipaypublickey, "RSA2");  //获得初始化的AlipayClient
         AlipayTradePagePayRequest alipayRequest =  new AlipayTradePagePayRequest(); //创建API对应的request
         alipayRequest.setReturnUrl( returnUrl );
         alipayRequest.setNotifyUrl( notifyUrl ); //在公共参数中设置回跳和通知地址
         JSONObject jsonObject = new JSONObject();
         jsonObject.put("out_trade_no",order.getOrderid());
         jsonObject.put("product_code","FAST_INSTANT_TRADE_PAY");
         jsonObject.put("total_amount",order.getOrderPay());
         jsonObject.put("subject","课程购买!");
         jsonObject.put("body","课程购买!");
         alipayRequest.setBizContent(jsonObject.toJSONString()); //填充业务参数
         String form= "" ;
         try  {
             form = alipayClient.pageExecute(alipayRequest).getBody();  //调用SDK生成表单
         }  catch  (AlipayApiException e) {
             e.printStackTrace();
         }
         return form;
     }
 
 
 
 //验签操作
  public Map callBack(HttpServletRequest request){
         Map map = verfiryCallbackReq(request);
         logger.debug("进入了支付宝的验签:参数为{}"+map);
         try {
             boolean  signVerified = AlipaySignature.rsaCheckV1(map, alipaypublickey, "utf-8", "RSA2");
 
             logger.debug("进入了支付宝的验签结果为:"+signVerified);
             if (signVerified){
                 return map;
             }else{
                 return null;
             }
 
         } catch (AlipayApiException e) {
             e.printStackTrace();
         }
         return null;
     }
     
     
 //    
 public Map verfiryCallbackReq(HttpServletRequest request){
         Map<String, String> retMap = new HashMap<String, String>();
         Set<Map.Entry<String, String[]>> entrySet = request.getParameterMap().entrySet();
         for (Map.Entry<String, String[]> entry : entrySet) {
             String name = entry.getKey();
             String[] values = entry.getValue();
             int valLen = values.length;
 
             if (valLen == 1) {
                 retMap.put(name, values[0]);
             } else if (valLen > 1) {
                 StringBuilder sb = new StringBuilder();
                 for (String val : values) {
                     sb.append(",").append(val);
                 }
                 retMap.put(name, sb.toString().substring(1));
             } else {
                 retMap.put(name, "");
             }
         }
         return retMap;
     }    
MyBatis分页插件
1.导包
 <dependency>
             <groupId>com.github.pagehelper</groupId>
             <artifactId>pagehelper-spring-boot-starter</artifactId>
             <version>1.3.0</version>
 </dependency>
2.使用
 
 //page页数 size每页大小
 PageHelper.startPage(page,size);
 进行数据库查询得到结果
 PageInfo.of(查询结果)
JWT使用
- 
导包 
   <dependency>
             <groupId>com.auth0</groupId>
             <artifactId>java-jwt</artifactId>
             <version>3.19.1</version>
         </dependency>
- 
使用 
     //获得令牌
     //map中存储的是用户信息
     public String signToken(Map map){
         //1.声明 算法以及 密钥
         Algorithm algorithm = Algorithm.HMAC256(securt);
         //2.声明头部信息
         Map headMap = new HashMap<>();
         headMap.put("typ","JWT");
         headMap.put("alg","HS256");
         //3.创建token 载荷信息
         String token = JWT.create().withHeader(headMap)
                 //1.签发人
                 .withIssuer("gzs")
                 //2.主题
                 .withSubject("login")
                 //3.受众
                 .withAudience("users")
                 //自定义载荷
                 .withClaim("name", map.get("name").toString())
                 .withClaim("id",map.get("id").toString())
                 .sign(algorithm);
 
         return token;
     }
     
     
 //解密将令牌传入返回不等于0解密成功    
 public Integer verfiy(String token){
         try {
             //1.声明算法
             Algorithm algorithm = Algorithm.HMAC256(securt);
             //声明解密对象
             JWTVerifier jwtVerifier = JWT.require(algorithm).withIssuer("gzs").build();
             //使用解密对象对token进行解密
             DecodedJWT verify = jwtVerifier.verify(token);
             String id = verify.getClaim("id").asString();
             return  Integer.valueOf(id);
         }catch (Exception e){
             System.out.println(e.getMessage());
             return 0;
 
         }
     }
拦截器
实现HandlerInterceptor(局部拦截)
实现WebMvcConfigurer(全局拦截 针对跨域)
 HandlerInterceptor
     preHandle
         调用controller之前 一般用来拦截未登录用户
     postHandle
         调用方法视图渲染前
     afterCompletion
         视图渲染后
         
         
         
 WebMvcConfigurer
     addInterceptors
         设置拦截放行
          public void addInterceptors(InterceptorRegistry registry) {
         //拦截所有/** 放行/user/**
         registry.addInterceptor(myInterceptor).addPathPatterns("/**")
                 .excludePathPatterns("/user/**","/swagger-resources/**", "/webjars/**", "/v2/**", "/swagger-ui.html/**")
                 .excludePathPatterns("/pay/callback");
     }
     addCorsMappings
         配置全局跨域
         public void addCorsMappings(CorsRegistry registry) {
         registry.addMapping("/**").allowCredentials(true).allowedOrigins("http://localhost:8080").allowedMethods("GET","POST");
     }
Linux部署
- 
docker安装 
- 
docke 运行数据库 
docker run -d -p 3306:3306 --name mysql -e MYSQL_ROOT_PASSWORD=密码 数据库标识
- 
连接数据库 将本地数据库内容导入云数据库 
- 
修改本地端口为云服务器端口 
- 
打包上传项目 
- 
使用nohup启动 
nohup java -jar 项目包 &
- 
可以使用nginx代理 
首先在/opt/nginx下建html conf包
映射到docker中
前端放入nginx中html
在conf中 配置nginx中的代理
启动nginx并映射
docker run -d -p 8000:8000 -p 9000:9000 --name nginx -v /opt/nginx/html:/usr/share/nginx/html -v /opt/nginx/conf:/etc/nginx/conf.d fa5269854a5e

 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号