SpringCloud入门学习

目录

      • 一.Eureka注册中心
        • 1.搭建注册中心
        • 2.服务注册
        • 3.服务发现调用
      • 二.负载均衡
        • 1.负载均衡流程
        • 2.负载均衡策略
        • 3.Ribbon饥饿加载
      • 三.Nacos注册中心
        • 1.启动nacos
        • 2.服务注册
        • 3.nacos服务分级储存模型
        • 4.集群及负载均衡策略
        • 5.环境隔离
        • 6.配置管理
      • 四.Feign
        • 1.基本使用
        • 2.Feign自定义配置
        • 3.Feign性能优化
        • 4.Feign最佳使用方式
      • 五.Geteway网关
        • 1.网关作用
        • 2.网关入门
        • 3.路由断言工厂
        • 4.路由过滤器GatewayFilter
        • 5.全局过滤器GlobalFilte

一.Eureka注册中心

1.搭建注册中心

①pom.xml文件引入eureka依赖 spring-cloud-starter-netflix-eureka-serve
②启动类添加注解 @EnableEurekaServer 在项目启动类上使用@EnableEurekaServer,可以将模块作为SpringCloud中的注册中心,提供服务注册和发现的能力
③配置application.yml

server:
  port: 8761 # 注册中心端口
spring:
  application:
    name: eurekaserver # eureka的服务名称
eureka:
  client:
    serviceUrl:   #注册中心访问地址
      defaultZone: http://localhost:8761/eureka/
    registerWithEureka: false  #是否注册自己,服务端就不用了注册自己了
    fetchRegistry: false  #是否从其他注册中心导入数据

2.服务注册

①pom.xml文件引入eureka依赖 spring-cloud-starter-netflix-eureka-client
②配置application.yml

server:
  port: 8763
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/cloud_order?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8
    username: root
    password: zks123456
    driver-class-name: com.mysql.cj.jdbc.Driver
  application:
    name: orderservice

mybatis:
  type-aliases-package: com.gzhu.pojo
  configuration:
    map-underscore-to-camel-case: true
  mapper-locations: classpath:mybatis/mapper/*.xml
  
eureka: #注册中心地址
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/
      
3.服务发现调用

①pom.xml文件引入eureka依赖 spring-cloud-starter-netflix-eureka-client
②配置application.yml

server:
  port: 8763
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/cloud_order?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8
    username: root
    password: zks123456
    driver-class-name: com.mysql.cj.jdbc.Driver
  application:
    name: orderservice

mybatis:
  type-aliases-package: com.gzhu.pojo
  configuration:
    map-underscore-to-camel-case: true
  mapper-locations: classpath:mybatis/mapper/*.xml

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

③启动类添加RestTemplate以及@LoadBalanced注解(用于负载均衡)

    @Bean
    @LoadBalanced
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }

④使用服务名称调用,如userservice就是一个微服务的名称

public Order queryOrderById(Long orderId) {
        //1.查询订单
        Order order =  orderMapper.findById(orderId);
        //2.利用RestTemplate发起http请求,查询用户
        String url = "http://userservice/user/"+order.getUserId();
        User user = restTemplate.getForObject(url, User.class);
        order.setUser(user);
        return order;
    }

二.负载均衡

1.负载均衡流程

SpringCloud入门学习_第1张图片

2.负载均衡策略

默认的负载均衡策略是轮询,可以通过两种方式改为随机方式
①代码方式
在某一个微服务的启动类定义一个新的IRule

@Bean
public IRule randonRule(){
  return new RandonRule();
}

则该微服务访问任何微服务的策略均为随机访问
②配置文件
在某个微服务的配置文件中添加以下配置,则针对该微服务的访问是随机

userservice:
     ribbon:
        NFLoadBalancerRuleClassName:com.netflix.loadbalancer.RandomRule# 负载均衡规则 
3.Ribbon饥饿加载

Ribbon默认是采用懒加载,即第一次访问时才会去创建LoadBalanceClient,请求时间会很长。而饥饿加载则会在项目启动时创建,降低第一次访问的耗时,通过下面配置开启饥饿加载:

ribbon:
  eager-load:
   enabled: true # 开启饥饿加载 
    clients: userservice # 指定对userservice这个服务饥饿加载

三.Nacos注册中心

1.启动nacos

cmd进入nacos的bin目录 输入startup.cmd -m standalone即可启动
SpringCloud入门学习_第2张图片
输入网址即为nacos的控制台

2.服务注册

父工程pom.xml引入依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>SpringCloud</artifactId>
    <packaging>pom</packaging>
    <version>1.0-SNAPSHOT</version>
    <modules>
        <module>eureka-server-8761</module>
        <module>config-server-8762</module>
        <module>order-server-8763</module>
        <module>user-server-8764</module>
        <module>feign-api</module>
        <module>gateway</module>
    </modules>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.4.12</version>
        <relativePath/>
    </parent>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <spring-cloud.alibaba.version>2021.1</spring-cloud.alibaba.version>
        <mysql.version>8.0.27</mysql.version>
        <mybatis.version>2.2.0</mybatis.version>
    </properties>


    <dependencyManagement>
        <dependencies>
            <!--nacos的管理依赖-->
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>${spring-cloud.alibaba.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!--mysql驱动 -->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>${mysql.version}</version>
            </dependency>
            <!--mybatis-->
            <dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
                <version>${m才ybatis.version}</version>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.22</version>
        </dependency>
    </dependencies>
</project>

微服务引入依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>SpringCloud</artifactId>
        <groupId>org.example</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>user-server-8764</artifactId>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
        </dependency>
        <!--nacos客户端依赖包 -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <!--nacos的配置管理依赖-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-bootstrap</artifactId>
            <version>3.0.4</version>
        </dependency>
    </dependencies>

</project>

application.yml进行配置,nacos默认端口为8848

SpringCloud入门学习_第3张图片
去控制台查看是否注册成功
SpringCloud入门学习_第4张图片

3.nacos服务分级储存模型

SpringCloud入门学习_第5张图片
一级是服务,例如userservice
二级是集群,例如杭州或上海
三级是实例,例如杭州机房的某台部署了userservice的服务器

4.集群及负载均衡策略

①搭建集群

SpringCloud入门学习_第6张图片
SpringCloud入门学习_第7张图片
配置文件集群名为GZHU,先启动两个实例,再修改配置文件的集群名称为QAU,再启动最后一个实例

spring:
	cloud:
	    nacos:
	      server-addr: localhost:8848
	      discovery:
	        cluster-name:XXX  #XXX自定集群名

userservice创建两个集群,其中集群GZHU包含两个实例,QAU包含一个实例
SpringCloud入门学习_第8张图片

②当调用微服务时,默认访问是随机的,即任何一个集群的微服务都可能被选到。如果在userservice配置文件配置以下信息,则访问会优先访问本地集群即优先访问GZHU集群的两个微服务,当本地集群挂掉后,则会跨集群访问即访问QAU集群,但这时会报一个跨集群警告

userservice:
   ribbon: 
    NFLoadBalancerRuleClassName:com.alibaba.cloud.nacos.ribbon.NacosRule # 负载均衡规则 

③访问权重设置
SpringCloud入门学习_第9张图片
Nacos控制台可以设置实例的权重值,0~1之间
同集群内的多个实例,权重越高被访问的频率越高
权重设置为0则完全不会被访问

5.环境隔离

默认所有的微服务都在public环境中
SpringCloud入门学习_第10张图片
新建命名空间
SpringCloud入门学习_第11张图片
命名空间id
SpringCloud入门学习_第12张图片
配置文件配置命名空间,则该微服务会到相应的空间,与其他空间的微服务没有任何交集
SpringCloud入门学习_第13张图片

6.配置管理

①控制台编写配置文件
SpringCloud入门学习_第14张图片
②读取配置文件
首先需要导入config依赖

<!--nacos的配置管理依赖-->
<dependency>
   <groupId>com.alibaba.cloud</groupId>
   <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<dependency>
   <groupId>org.springframework.cloud</groupId>
   <artifactId>spring-cloud-starter-bootstrap</artifactId>
   <version>3.0.4</version>
</dependency>

然后在userservice中的resource目录添加一个bootstrap.yml文件,这个文件是引导文件,优先级高于application.yml。在微服务中添加bootstrap.yml,配置nacos地址、当前环境、服务名称、文件后缀名。这些决定了程序启动时去nacos读取哪个文件
这里建议使用低版本的config依赖,高版本的依赖需要额外导入bootstrap依赖

spring:
  application:
    name: userservice #服务名称
  profiles:
    active: dev #开发环境
  cloud:
    nacos:
      config:
        server-addr: localhost:8848 #nacos地址
        file-extension: yaml #文件后缀名

③测试
SpringCloud入门学习_第15张图片
时间格式按照配置文件生成,说明配置文件生效
SpringCloud入门学习_第16张图片
④热部署配置文件
Nacos中的配置文件变更后,微服务无需重启就可以感知
方式一:在@Value注入的变量所在类上添加注解@RefreshScope
SpringCloud入门学习_第17张图片
方式二:使用@ConfigurationProperties注解

@Component
@Data
@ConfigurationProperties(prefix = "pattern")
public class PatternProperties {
   private String dateformat;
}

⑤多环境配置共享
需要在控制台创建一个配置文件名为XXX.yaml,XXX为服务名,这样该服务的不同实例均可以在启动时读取到配置的信息(IDEA中无需配置任何信息)
SpringCloud入门学习_第18张图片
优先级:
[服务名]-[环境].yaml >[服务名].yaml > 本地配置(application.yml)

四.Feign

1.基本使用

①引入依赖

<dependency>
   <groupId>org.springframework.cloud</groupId>
   <artifactId>spring-cloud-starter-openfeign</artifactId>
   <version>3.0.4</version>
</dependency>

②启动类添加注解 @EnableFeignClients
③编写Client接口

@FeignClient("userservice") #指定服务名
public interface UserClient {
    @GetMapping("/user/{id}")
    User findById(@PathVariable("id") Long id);
}

④使用Client接口进行调用

@Service
public class OrderService {
    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private UserClient userClient;

    public Order queryOrderById(Long orderId) {
        Order order =  orderMapper.findById(orderId);
        User user = userClient.findById(order.getUserId());
        order.setUser(user);
        return order;
  
    }
}
2.Feign自定义配置

SpringCloud入门学习_第19张图片
配置文件方式进行配置

feign:
  client:
    config:
      default: # 这里用default就是全局配置,如果是写服务名称,则是针对某个微服务的配置
        loggerLevel: FULL #  日志级别 
3.Feign性能优化

①日志级别尽量用basic
②连接池优化 HttpClient或OKHttp代替URLConnection(默认连接池)
引入依赖

<!--httpClient的依赖 -->
<dependency>
  <groupId>io.github.openfeign</groupId>
  <artifactId>feign-httpclient</artifactId>
</dependency>

配置参数

feign:
  client:
    config:
      default:
        loggerLevel: FULL
  httpclient:
    enabled: true
    max-connections: 200 # 最大的连接数
    max-connections-per-route: 50 # 每个路径的最大连接数
4.Feign最佳使用方式

统一编写一个Module模块feign-api,用来管理所有的feign接口
①引入依赖

<dependency>
   <groupId>org.springframework.cloud</groupId>
   <artifactId>spring-cloud-starter-openfeign</artifactId>
   <version>3.0.4version>
</dependency>

②编写接口即可(相关的pojo全部引入)

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

③消费者使用方式

1.首先也要导入spring-cloud-starter-openfeign依赖(如果版本较新,还需要导入spring-cloud-loadbalancer依赖)

2.在启动类上指定要使用的FeignClient字节码 @EnableFeignClients(clients = {UserClient.class})

3.并且注入相关的接口

@Autowired
private  UserClient userClient;

即可正常使用feign-api中所定义的接口

五.Geteway网关

1.网关作用

身份认证和权限校验:对用户请求做身份认证、权限校验
服务路由、负载均衡:将用户请求路由到微服务,并实现负载均衡
请求限流:对用户请求做限流

2.网关入门

①引入依赖

<dependencies>
        <!--nacos服务注册发现依赖-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <!--网关gateway依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
            <version>3.0.0</version>
        </dependency>
        <!--fegin组件-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
            <version>3.0.4</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-loadbalancer</artifactId>
            <version>3.0.4</version>
        </dependency>
    </dependencies>

②编写启动类及配置文件

server:
  port: 10010 # 网关端口
spring:
  application:
    name: gateway # 服务名称
  cloud:
    nacos:
      server-addr: localhost:8848 # nacos地址
    gateway:
      routes: # 网关路由配置
        - id: user-service # 路由id,自定义,只要唯一即可
          # uri: http://127.0.0.1:8081 # 路由的目标地址 http就是固定地址
          uri: lb://userservice # 路由的目标地址 lb就是负载均衡,后面跟服务名称
          predicates: # 路由断言,也就是判断请求是否符合路由规则的条件
            - Path=/user/** # 这个是按照路径匹配,只要以/user/开头就符合要求
        - id: order-service # 路由id,自定义,只要唯一即可
            # uri: http://127.0.0.1:8081 # 路由的目标地址 http就是固定地址
          uri: http://127.0.0.1:8763 # 路由的目标地址 lb就是负载均衡,后面跟服务名称
          predicates: # 路由断言,也就是判断请求是否符合路由规则的条件
            - Path=/order/** # 这个是按照路径匹配,只要以/user/开头就符合要求

③测试
在这里插入图片描述

3.路由断言工厂

SpringCloud入门学习_第20张图片

4.路由过滤器GatewayFilter

SpringCloud入门学习_第21张图片
详情链接: https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#gatewayfilter-factories

5.全局过滤器GlobalFilte

全局过滤器的作用是什么?
对所有路由都生效的过滤器,并且可以自定义处理逻辑
实现全局过滤器的步骤?
1.实现GlobalFilter接口
2.添加@Order注解(过滤器顺序)或实现Ordered接口
3.编写处理逻辑

@Order(-1)
@Component
public class AuthorizeFilter implements GlobalFilter {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        //1.获取请求参数
        MultiValueMap<String, String> params = exchange.getRequest().getQueryParams();
        // 2.获取authorization参数
        String auth = params.getFirst("authorization");
        //3.校验
        if ("admin".equals(auth)) {
            //放行
            return chain.filter(exchange);
        }
        //4.拦截
        //4.1禁止访问
        exchange.getResponse().setRawStatusCode(HttpStatus.SC_UNAUTHORIZED);
        //4.2处理结束
        return exchange.getResponse().setComplete();
        
    }
}

过滤器执行顺序:
①order值越小,优先级越高
②当order值一样时,顺序是defaultFilter最先,然后是局部的路由过滤器,最后是全局过滤器

你可能感兴趣的:(微服务,spring,cloud,spring,java)