项目中常用技术点

三阶段知识点总结

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;
}
}

}
posted @   永远的幼稚  阅读(147)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
点击右上角即可分享
微信分享提示