Springcloud笔记超级详细

目录

1创建简单的springcloud项目

1.1先创建一个maven的空项目

1.2创建子模块

2.将两个模块加入到Eureka服务中

2.1创建Eureka模块

 2.2将其他模块注册到Eureka服务中

2.3实现负载均衡

2.4修改负载均衡策略

3.Nacos

3.1下载配置Nacos

3.2Springcloud集成Nacos

3.3Nacos的集群配置

3.4修改权重

3.5 命名空间和临时实例

3.6Nacos统一管理配置

4.Feign替代RestTemplate

4.1配置Feign

4.2Feign的性能优化

4.3把feign提取出来成为一个服务

5.gateway网关

5.1创建一个服务

2.predicates Factory断言工厂

3.Gatewayfiler网关过滤器

4.GlobaFilter全局过滤器

5.跨域问题处理

6.Sentinel

 6.1流控

6.1.1qps表示每秒只能多少次访问

6.1.2线程表示每秒只能有多少个线程访问​

6.1.3关联流控

6.1.4Warmup

6.1.5排队等待


1创建简单的springcloud项目

1.1先创建一个maven的空项目

Springcloud笔记超级详细_第1张图片

这里直接下一步就好

创建好了后直接把src目录删了

Springcloud笔记超级详细_第2张图片

 然后就是写xml配置

这里看需求



    4.0.0

    org.example
    Springcloud
    1.0-SNAPSHOT


    pom

    
        org.springframework.boot
        spring-boot-starter-parent
        2.6.1
        
    

    
        UTF-8
        UTF-8
        1.8
        2021.0.1
        5.1.47
        2.1.1
    
    
        
            
            
                org.springframework.cloud
                spring-cloud-dependencies
                ${spring-cloud.version}
                pom
                import
            
            
            
                mysql
                mysql-connector-java
                ${mysql.version}
            
            
            
                org.mybatis.spring.boot
                mybatis-spring-boot-starter
                ${mybatis.version}
            
        
    
    
        
            org.projectlombok
            lombok
        
    

1.2创建子模块

Springcloud笔记超级详细_第3张图片

配置xml文件



    
        Springcloud
        org.example
        1.0-SNAPSHOT
    
    4.0.0

    org.user
    user-service

    
        8
        8
    
    
        
            org.springframework.boot
            spring-boot-starter-web
        
        
            mysql
            mysql-connector-java
        
        
            com.baomidou
            mybatis-plus
        
        
            com.baomidou
            mybatis-plus-boot-starter
        
    

配置创建springboot启动类

在配置文件里面写数据库的连接不然会报错

最后写一个接口测试一下是否成功,端口号是自己设置的

 没问题的话这个user模块就ok了Springcloud笔记超级详细_第4张图片

我们在创建一个模块重复步骤我们就省略了

我们可以看到订单模块有一个用户我们让订单模块调用户模块的服务

RestTemplate这个是夸模块调用的核心

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;

/**
 * @Classname OrderApplication
 * @Description TODO
 * @Date 2022/3/26 17:09
 * @Created lijiafen
 */
@SpringBootApplication
public class OrderApplication {
    public static void main(String[] args) {
        SpringApplication.run(OrderApplication.class,args);
    }
    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}
import com.order.dao.OrderMapper;
import com.order.pojo.tbOrder;
import com.order.pojo.tbUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

/**
 * @Classname OrderController
 * @Description TODO
 * @Date 2022/3/26 17:14
 * @Created lijiafen
 */
@RestController()
@RequestMapping("order")
public class OrderController {
    @Autowired
    OrderMapper mapper;
    @Autowired
    RestTemplate restTemplate;
    @GetMapping("{id}")
    public Object getOrder(@PathVariable("id") Long id) {
        if (id==null){
            return "未输入id";
        }
        tbOrder tbOrder = mapper.selectById(id);
        String url = "http://localhost:8890/user/"+tbOrder.getUserId();
       tbUser user = restTemplate.getForObject(url, tbUser.class);
       tbOrder.setUser(user);
       return tbOrder;
    }
}

这里就是调用用户模块的实现

Springcloud笔记超级详细_第5张图片

 但是你怎么知道用户模块没有挂呢,下面我们引入一个springcloud的核心之一Euake

2.将两个模块加入到Eureka服务中

2.1创建Eureka模块

一样的我们先创建一个子模块这个是依赖文件



    
        Springcloud
        org.example
        1.0-SNAPSHOT
    
    4.0.0

    Springclude-eureka

    
        8
        8
    
    
        
            org.springframework.boot
            spring-boot-starter-web
        
        
            org.springframework.cloud
            spring-cloud-starter-netflix-eureka-server
        
    

这个是配置文件

server:
  port: 5561
eureka:
  instance:
    hostname: localhost
  client:
    fetch-registry: false
    register-with-eureka: false//这个是是否把自己添加到服务中
    service-url:
      defaultZone: http://localhost:5561/eureka/

一定要在启动类上加上这个注解

package com.fen;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

/**
 * @Classname Application
 * @Description TODO
 * @Date 2022/3/26 18:54
 * @Created lijiafen
 */
@SpringBootApplication
@EnableEurekaServer
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class,args);
    }
}

如果进入这个页面的话就说明ok了

Springcloud笔记超级详细_第6张图片

 2.2将其他模块注册到Eureka服务中

在其他模块中引入这个依赖

    
                org.springframework.cloud
                spring-cloud-starter-netflix-eureka-server
            

配置文件中加入这些配置端口你们的Eureka模块是什么端口这里就写什么

eureka:
  client:
    service-url:
      defaultZone: http://localhost:5561/eureka/

在主类上加上这个注解@EnableEurekaClient


import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;

/**
 * @Classname OrderApplication
 * @Description TODO
 * @Date 2022/3/26 17:09
 * @Created lijiafen
 */
@SpringBootApplication
@EnableEurekaClient
public class OrderApplication {
    public static void main(String[] args) {
        SpringApplication.run(OrderApplication.class,args);
    }
    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

 如果出现这个就ok了Springcloud笔记超级详细_第7张图片

2.3实现负载均衡

我们把实例都注册的到eureka中之后前面有订单模块调用用户模块

@LoadBalanced我们加上这个注解

@SpringBootApplication
@EnableEurekaClient
public class OrderApplication {
    public static void main(String[] args) {
        SpringApplication.run(OrderApplication.class,args);
    }
    @Bean
    @LoadBalanced //这个注解是开启负载均衡
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

我们把user模块分出一个服务

 点击复制配置修改端口

 然后就变成这样的

Springcloud笔记超级详细_第8张图片

 我们全部重启一下看看Eureka里面有了两个user的服务

Springcloud笔记超级详细_第9张图片

package com.order.controller;

import com.order.dao.OrderMapper;
import com.order.pojo.tbOrder;
import com.order.pojo.tbUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

/**
 * @Classname OrderController
 * @Description TODO
 * @Date 2022/3/26 17:14
 * @Created lijiafen
 */
@RestController()
@RequestMapping("order")
public class OrderController {
    @Autowired
    OrderMapper mapper;
    @Autowired
    RestTemplate restTemplate;
    @GetMapping("{id}")
    public tbOrder getOrder(@PathVariable("id") Long id) {
        tbOrder tbOrder = mapper.selectById(id);
        String url = "http://userservice/user/"+tbOrder.getUserId();
    这里就不填端口号了我们直接填userservice不指定端口
       tbUser user = restTemplate.getForObject(url, tbUser.class);
       tbOrder.setUser(user);
       return tbOrder;
    }
}

我们用postman多测试几遍这个接口

Springcloud笔记超级详细_第10张图片

 

Springcloud笔记超级详细_第11张图片

我们可以看到两个user模块都输出了日志那说明就ok了

2.4修改负载均衡策略

默认的话是轮询的策略我们这里配置一个bean修改为随机

@SpringBootApplication
@EnableEurekaClient
public class OrderApplication {
    public static void main(String[] args) {
        SpringApplication.run(OrderApplication.class,args);
    }
    @Bean
    @LoadBalanced //这个注解是开启负载均
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }

    @Bean
    public IRule iRule(){
        return new RandomRule();/*改变负载均衡的策略这个是随机默认是轮训方式*/
    }
}

3.Nacos

3.1下载配置Nacos

https://nacos.io/zh-cn/

下载好了之后解压到一个没有中文目录的文件夹里面

startup.sh -m standalone

cmd运行起来

Springcloud笔记超级详细_第12张图片

我这里因为有浏览器缓存所以不用密码账号和密码是nacos

Springcloud笔记超级详细_第13张图片

3.2Springcloud集成Nacos

因为我们这前用了Eureka所以我们先把Eureka的配置注释掉

在到父文件里面引入Nacos的依赖


                com.alibaba.cloud
                spring-cloud-alibaba-dependencies
                2.2.6.RELEASE
                pom
                import
            

在到用户和订单模块里面添加Nacos的依赖

 
            com.alibaba.cloud
            spring-cloud-starter-alibaba-nacos-discovery
        

在配置文件里面添加Nacos的服务地址配置

 spring:
    cloud:
      nacos:
        server-addr: 127.0.0.1:8848

注意要把之前Eureka的配置全部注释掉然后运行服务要先把Nacos的服务开启

Springcloud笔记超级详细_第14张图片

如果出现这个界面显示了三个服务就ok了

3.3Nacos的集群配置

 cloud:
    nacos:
      server-addr: 127.0.0.1:8848
      discovery:
        cluster-name: NC #集群名称南昌

我们运行两个userService的服务

Springcloud笔记超级详细_第15张图片

然后在修改配置文件把南昌改成别的城市

 cloud:
    nacos:
      server-addr: 127.0.0.1:8848
      discovery:
        cluster-name: SZ #集群名称深圳

然后打开Nacos的控制台

Springcloud笔记超级详细_第16张图片

 这样的话那就是配置成功了

总结一下

Springcloud笔记超级详细_第17张图片

 我们为orderservice也配置一下集群和上面做法一样

Springcloud笔记超级详细_第18张图片

我们让他优先访问本地集群配置yml文件就会优先访问本地集群

userservice:
  ribbon:
    NFLoadBalancerRuleClassNane: com.alibaba.cloud.nacos.ribbon.NacosRule


3.4修改权重

我们可以通过修改改服务的权重来控制服务器的访问量

Springcloud笔记超级详细_第19张图片

3.5 命名空间和临时实例

新建一个命名空间

Springcloud笔记超级详细_第20张图片

 然后在配置文件里面配置

  cloud:
    nacos:
      server-addr: 127.0.0.1:8848
      discovery:
        cluster-name: SZ #集群名称南昌
        namespace: lijia520 #命名空间
        ephemeral: false #是否为临时实例

然后就是临时实例的问题如果不是临时实例的话服务挂了之后Nacos是不会把该服务剔除的

如果是临时实例的话就会把该服务剔除而是会一直等待该服务恢复,除非你主动把他剔除

Springcloud笔记超级详细_第21张图片

Springcloud笔记超级详细_第22张图片

3.6Nacos统一管理配置

点击加号新建配置

Springcloud笔记超级详细_第23张图片

 Springcloud笔记超级详细_第24张图片

 然后就是写bootstrap文件因为这个文件会比application文件先被读取

spring:
  application:
    name: orderservice-dev
  cloud:
    nacos:
      server-addr: localhost:8848
      config:
        file-extension: yaml

 添加依赖,如果cloud的版本是2020.0以上的还要多加一个依赖


            com.alibaba.cloud
            spring-cloud-starter-alibaba-nacos-config
        
        
        
            org.springframework.cloud
            spring-cloud-starter-bootstrap
        

然后我们写一个接口测试一下

  @Value("${pattern.dateformat}")
    String name;


 @GetMapping("/name")
    public String name(){

      return LocalDateTime.now().format(DateTimeFormatter.ofPattern(name));
    }

Springcloud笔记超级详细_第25张图片

那就说明读取到了里面的配置,如果需要热加载的话在controller上面加一个注解

@RefreshScope

这个注解是配置热更新的注解

4.Feign替代RestTemplate

4.1配置Feign

导依赖开启注解支持

 
        
            org.springframework.cloud
            spring-cloud-starter-openfeign
        

在启动 类上添加这个注解开启自动装配

@EnableFeignClients //开启feign自动装配支持

然后我们创建一个包

Springcloud笔记超级详细_第26张图片

 里面创建一个接口

package com.order.clients;

import com.order.pojo.tbUser;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;

@FeignClient("userservice")
public interface UserClient {
    @GetMapping("/user/{id}")
    tbUser GetById(@PathVariable("id") Long id);
}

这里的参数对应提供者的参数下面是调用的代码

 @Autowired
    UserClient userClient;
 @GetMapping("{id}")
    public tbOrder getOrder(@PathVariable("id") Long id) {
        tbOrder tbOrder = mapper.selectById(id);
        Long userId= tbOrder.getUserId();
       tbUser user = userClient.GetById(userId);
       tbOrder.setUser(user);
       return tbOrder;
    }

还要注意的就是如果使用的是springcloud是2021.0.1的话我们要改一下因为fegin自带了rebbin

我们要把nacos里面的不使用


            com.alibaba.cloud
            spring-cloud-starter-alibaba-nacos-discovery
            2.2.6.RELEASE
            
                
                    org.springframework.cloud
                    spring-cloud-starter-netflix-ribbon
                
            
        

这个困扰了我一下午终于解决

4.2Feign的性能优化

我们这边用阿帕奇的http连接池

  
            io.github.openfeign
            feign-httpclient
        

编写配置文件

feign:
  client:
    config:
      default: #全局日志
        loggerLevel: BASIC #日志级别
  httpclient:
    enabled: true  #开启feign对httpclient的支持
      max-connections: 200 #最大连接数
      max-connections-per-route: 50 #每个路径的最大连接数

4.3把feign提取出来成为一个服务

Springcloud笔记超级详细_第27张图片

 Springcloud笔记超级详细_第28张图片

Springcloud笔记超级详细_第29张图片 然后调用这个接口就ok了

 @Autowired
    UserClient userClient;

    @GetMapping("{id}")
    public tbOrder getOrder(@PathVariable("id") Long id) {
        tbOrder tbOrder = mapper.selectById(id);
        Long userId= tbOrder.getUserId();
       tbUser user = userClient.GetById(userId);
       tbOrder.setUser(user);
       return tbOrder;
    }

 Springcloud笔记超级详细_第30张图片


5.gateway网关

5.1创建一个服务

        
            
            com.alibaba.cloud
            spring-cloud-starter-alibaba-nacos-discovery
        

        
            
            org.springframework.cloud
            spring-cloud-starter-gateway
        

        
        
            org.springframework.cloud
            spring-cloud-starter-loadbalancer
        

Springcloud笔记超级详细_第31张图片

 配置文件

spring:
  application:
    name: gateway
  cloud:
    nacos:
      server-addr: 127.0.0.1:8848 #加入到nacos里面
    gateway:
      routes:
        - id: user-service #路由标识必须唯一
          uri: lb://userservice #路由的目标地址
          predicates:
            - Path=/user/** #断言判断请求路径是否以/user开头如果是就符合规则这里一定要大写P
        - id: order-service
          uri: lb://orderservice-dev
          predicates:
            - Path=/order/**
server:
  port: 10086

Springcloud笔记超级详细_第32张图片

Springcloud笔记超级详细_第33张图片

 这里我们请求的是网关的端口通过网关转发到user服务里面

2.predicates Factory断言工厂

Springcloud笔记超级详细_第34张图片

上面我们用的就是Path

Springcloud笔记超级详细_第35张图片

 https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#gateway-request-predicates-factoriesz

这个是链接可以去看看

我们来试一个

gateway:
      routes:
        - id: user-service #路由标识必须唯一
          uri: lb://userservice #路由的目标地址
          predicates:
            - Path=/user/** #断言判断请求路径是否以/user开头如果是就符合规则这里一定要大写P
            - After=2032-01-20T17:42:47.789-07:00[Asia/Shanghai]
        - id: order-service
          uri: lb://orderservice-dev
          predicates:
            - Path=/order/**
            - After=2032-01-20T17:42:47.789-07:00[Asia/Shanghai] #这个规则是需要在2017年之后就符合规则

Springcloud笔记超级详细_第36张图片

 我们就设置成功,还有很多断言可以去试试

3.Gatewayfiler网关过滤器

Springcloud笔记超级详细_第37张图片

Springcloud笔记超级详细_第38张图片

spring官网有很多的过滤器可以去看看

    gateway:
      routes:
        - id: user-service #路由标识必须唯一
          uri: lb://userservice #路由的目标地址
          predicates:
            - Path=/user/** #断言判断请求路径是否以/user开头如果是就符合规则这里一定要大写P
            - After=2021-01-20T17:42:47.789-07:00[Asia/Shanghai]
          filters:
            - AddRequestHeader=Name,lijiafen #请求头添加信息

我们来试一个,我们配的是user服务我们在user服务的controller接口里面接收一下看看能不能接收的名字

  @RequestMapping("{id}")
    public tbUser selectUser(@PathVariable("id") int id,@RequestHeader("Name") String name) {
        System.out.println("name是"+name);
        return userDao.selectById(id);
    }

Springcloud笔记超级详细_第39张图片

控制台也打印了就ok了这样一个一个服务配有点麻烦我们有一种全局配置的方法

    gateway:
      routes:
        - id: user-service #路由标识必须唯一
          uri: lb://userservice #路由的目标地址
          predicates:
            - Path=/user/** #断言判断请求路径是否以/user开头如果是就符合规则这里一定要大写P
            - After=2021-01-20T17:42:47.789-07:00[Asia/Shanghai]
          filters:
            - AddRequestHeader=Name,lijiafen #请求头添加信息
        - id: order-service
          uri: lb://orderservice-dev
          predicates:
            - Path=/order/**
            - After=2021-01-20T17:42:47.789-07:00[Asia/Shanghai] #这个规则是需要在2017年之后就符合规则
      default-filters: #全局配置过滤器
        - AddRequestHeader=Name,lijiafen #请求头添加信息

我们在order服务里面也添加一下看看能不能生效

Springcloud笔记超级详细_第40张图片

说明我们全局配置就ok了

4.GlobaFilter全局过滤器

 具体代码


/**
 * @Classname LandFilter
 * @Description TODO
 * @Date 2022/4/28 17:27
 * @Created lijiafen
 */

public class LandFilter implements GatewayFilter , Ordered {
    @Override
    public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        //我们获取前端传来的参数
        ServerHttpRequest request = exchange.getRequest();
        //获取请求的参数
        MultiValueMap queryParams = request.getQueryParams();
        String name = queryParams.getFirst("Name");
        if ("小p".equals(name)){
            /*如果相等就放行*/
            return chain.filter(exchange);
        }
        /*设置状态码*/
        exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
        return exchange.getResponse().setComplete();
    }

    @Override
    public int getOrder() {
        return -1; /*这里是定义过滤器的执行顺序*/
    }
}

5.跨域问题处理

Springcloud笔记超级详细_第41张图片

 这是一个很明显的跨域问题

配置如下

      globalcors:
        cors-configurations:
          '[/**]':
            # 允许任何域名使用
            allowedOrigins: "*"
            # 允许任何头
            allowedHeaders: "*"
            # 允许任何方法(post、get等)
            allowedMethods: "*"
            # sessionid 多次访问一致
            allowCredentials: true
        # 允许来自所有域名(allowedOrigins)的所有请求方式(allowedMethods)发出CORS请求
        add-to-simple-url-handler-mapping: true   # 允许来自所有域名(allowedOrigins)的所有请求方式(allowedMethods)发出CORS请求

6.Sentinel

这个是他的中文文档介绍 · alibaba/Sentinel Wiki · GitHub

我们下好了后直接java-jar运行

Springcloud笔记超级详细_第42张图片

Springcloud笔记超级详细_第43张图片

 账号密码都是sentinel

然后我们创建一个服务把它接入nacos

dependency>
            org.springframework.boot
            spring-boot-starter-web
        

        
            
            com.alibaba.cloud
            spring-cloud-starter-alibaba-nacos-discovery
        

        
            
            com.alibaba.cloud
            spring-cloud-starter-alibaba-sentinel
        

        
            
            com.alibaba.csp
            sentinel-datasource-nacos
        

        
            org.springframework.cloud
            spring-cloud-starter-openfeign
        

配置文件

server:
  port: 1314
spring:
  application:
    name: sentinel
  cloud:
    nacos:
      server-addr: 127.0.0.1:8848
    sentinel:
      transport:
        dashboard: 127.0.0.1:8080 #这个是sentinel前台端口
        port: 8719 #这个是后台端口
  main:
    allow-circular-references: true #如果是使用的2021.0的话加这个配置

要执行一次之后就可以显示

Springcloud笔记超级详细_第44张图片

这个是我们开放的两个后端接口也就是一个链路下面的两个节点

 

 6.1流控

添加流控规则

6.1.1qps表示每秒只能多少次访问

Springcloud笔记超级详细_第45张图片

 这个就是每秒超过了1次访问就报错

Springcloud笔记超级详细_第46张图片

 6.1.2线程表示每秒只能有多少个线程访问Springcloud笔记超级详细_第47张图片

 这边手速不够就不试了。。。。。

6.1.3关联流控

Springcloud笔记超级详细_第48张图片

 如果name这个接口访问数超标的话我们user就会挂掉

我们用apipost一直访问这个 接口然后我们的user就挂掉了

Springcloud笔记超级详细_第49张图片

 6.1.4Warmup

Springcloud笔记超级详细_第50张图片

Springcloud笔记超级详细_第51张图片

6.1.5排队等待

Springcloud笔记超级详细_第52张图片

 这个就不必多说了吧

你可能感兴趣的:(笔记,spring,java,springcloud)