1. 程式人生 > 其它 >專案中常用技術點

專案中常用技術點

三階段知識點總結

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(有序、去重)
  1. 導包

  2. 配置

 #埠號
 Spring.redis.prot=6379
 #伺服器
 Spring.redis.host=
  1. 使用

  • 快取同步

當資料庫修改後怎麼同步redis

1.修改資料庫時首先判斷redis中是否有該值對應的key如果有的直接刪除key

2.修改資料庫時同時修改redis中的資料

  • 快取穿透

當用戶使用資料庫不存在的key進行訪問時,會穿過redis直接訪問資料庫

1.給這個key設定null值 並設定定時

  • 快取擊穿

當redis中的key被高併發請求訪問時 該key突然失效 請求會全部訪問到資料庫 造成資料庫壓力增大

1.可以設定key永不失效

  • 快取雪崩

和快取擊穿相差不大 雪崩是大量key失效

1.設定加長失效時間

2.避免快取同一時間失效

  • redis持久化

    1. AOF

    持續的日誌新增,操作一次redis就會記錄一次日誌

    1. RDB

    快照,每30秒,對當前redis中的記憶體進行儲存記錄到磁碟中

支付寶支付

  1. 導包

    <dependency>
            <groupId>com.alipay.sdk</groupId>
            <artifactId>alipay-sdk-java</artifactId>
            <version>4.22.57.ALL</version>
        </dependency>
  1. 配置

 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. 使用(工具類)

 流程: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使用

  1. 導包

  <dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>3.19.1</version>
</dependency>
  1. 使用

    //獲得令牌
//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部署

  1. docker安裝

  • docke 執行資料庫

docker run -d -p 3306:3306 --name mysql -e MYSQL_ROOT_PASSWORD=密碼 資料庫標識

  1. 連線資料庫 將本地資料庫內容匯入雲資料庫

  2. 修改本地埠為雲伺服器埠

  3. 打包上傳專案

  4. 使用nohup啟動

nohup java -jar 專案包 &

檢視日誌 tail -f nohup.out

  1. 可以使用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

Aop實現

@Aspect類上加註解表示切面類
//定義切面方法 
使用@Pointcut()定義路徑
第一個*表示返回值 剩下表示路徑
@Pointcut(value = "execution(* *.*.*.*.impl.*.*(..))")
public void pt1(){
}
//在方法上加
@Around(value = "pt1()")
@Component
@Aspect
public class LoggerAop {
private Logger logger = LoggerFactory.getLogger(LoggerAop.class);

/**
* 定義切點
* 第一個*返回值
* *.*.*.*.impl.*.*(..)表示路徑到方法引數
*/

/**
* 1.定義切面類@Aspect
* 2.定義切點方法使用@Pointcut()註解 切點就是日誌的使用域
* 3.定義日誌使用方式@Around(value="切點")
* 4.在定義的方法中傳參ProceedingJoinPoint 通過getSignature獲取執行的方法 通過getArgs獲取方法的引數
*/
@Pointcut(value = "execution(* *.*.*.*.impl.*.*(..))")
public void pt1(){
}

@Around(value = "pt1()")
public Object around(ProceedingJoinPoint proceedingJoinPoint){

logger.debug("進入");
//獲取執行方法
MethodSignature signature = (MethodSignature)proceedingJoinPoint.getSignature();
//獲得引數
Object[] args = proceedingJoinPoint.getArgs();
Date date = new Date();
String s = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(date);

logger.debug("進入時間:"+s);
logger.debug("進入執行的方法:"+signature.getMethod());
logger.debug("當前引數:"+ Arrays.toString(args));
Object proceed = null;
try {
proceed = proceedingJoinPoint.proceed();
logger.debug("返回的引數:"+signature.getReturnType());
return proceed;
}catch (Throwable e) {
e.printStackTrace();
logger.error("方法:"+signature.getMethod()+"發生異常:"+e.getMessage());
}finally {
return proceed;
}
}

}