微服务技术栈2022-学习这一篇就够了

一.微服务技术栈

1.1认识微服务

1.1.1内容

微服务技术栈2022-学习这一篇就够了_第1张图片
微服务技术栈2022-学习这一篇就够了_第2张图片
微服务技术栈2022-学习这一篇就够了_第3张图片

1.1.2三种技术对比

微服务技术栈2022-学习这一篇就够了_第4张图片

1.1.3企业常见的四种情况

微服务技术栈2022-学习这一篇就够了_第5张图片

1.1.4SpringCloud

官网:https://spring.io/projects/spring-cloud
微服务技术栈2022-学习这一篇就够了_第6张图片
注意版本兼容问题
微服务技术栈2022-学习这一篇就够了_第7张图片

1.2分布式服务架构案例

1.2.1服务拆分

微服务技术栈2022-学习这一篇就够了_第8张图片
1)导入sql
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">
    <parent>
        <artifactId>cloud-demo</artifactId>
        <groupId>cn.itcast.demo</groupId>
        <version>1.0</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>user-service</artifactId>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <!--mybatis-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
        </dependency>
    </dependencies>
    <build>
        <finalName>app</finalName>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

3)运行测试
微服务技术栈2022-学习这一篇就够了_第9张图片
4)总结
微服务技术栈2022-学习这一篇就够了_第10张图片

1.2.2 服务远程调用

微服务技术栈2022-学习这一篇就够了_第11张图片
微服务技术栈2022-学习这一篇就够了_第12张图片
微服务技术栈2022-学习这一篇就够了_第13张图片

1.3eureka注册中心

1.3.1eureka的作用

微服务技术栈2022-学习这一篇就够了_第14张图片
微服务技术栈2022-学习这一篇就够了_第15张图片
微服务技术栈2022-学习这一篇就够了_第16张图片

1.3.2eureka服务的搭建
  1. 引入eureka依赖
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>

2)编写启动类

给eureka-server服务编写一个启动类,一定要添加一个@EnableEurekaServer注解,开启eureka的注册中心功能:

package cn.itcast.eureka;

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

@SpringBootApplication
@EnableEurekaServer
public class EurekaApplication {
    public static void main(String[] args) {
        SpringApplication.run(EurekaApplication.class, args);
    }
}

3)编写配置文件

server:
  port: 10086
spring:
  application:
    name: eureka-server
eureka:
  client:
    service-url: 
      defaultZone: http://127.0.0.1:10086/eureka

4)启动并访问
http://127.0.0.1:10086 效果如下
微服务技术栈2022-学习这一篇就够了_第17张图片

1.3.2eureka服务注册

1)依赖

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

2)配置文件

spring:
  application:
    name: userservice
eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:10086/eureka

3)启动多个user-service实例
微服务技术栈2022-学习这一篇就够了_第18张图片
微服务技术栈2022-学习这一篇就够了_第19张图片
4)启动
微服务技术栈2022-学习这一篇就够了_第20张图片
在这里插入图片描述

1.3.2eureka服务发现

1)依赖

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

2)配置文件

spring:
  application:
    name: orderservice
eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:10086/eureka

3)服务拉取和负载均衡
在order-service的OrderApplication中,给RestTemplate这个Bean添加一个@LoadBalanced注解:
微服务技术栈2022-学习这一篇就够了_第21张图片
修改order-service服务中的cn.itcast.order.service包下的OrderService类中的queryOrderById方法。修改访问的url路径,用服务名代替ip、端口:
微服务技术栈2022-学习这一篇就够了_第22张图片

1.4Ribbon负载均衡原理

微服务技术栈2022-学习这一篇就够了_第23张图片
微服务技术栈2022-学习这一篇就够了_第24张图片

微服务技术栈2022-学习这一篇就够了_第25张图片
微服务技术栈2022-学习这一篇就够了_第26张图片

1.5nacos

1.5.1nacos注册中心
  1. 引入依赖
    在cloud-demo父工程的pom文件中的中引入SpringCloudAlibaba的依赖:
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-alibaba-dependencies</artifactId>
    <version>2.2.6.RELEASE</version>
    <type>pom</type>
    <scope>import</scope>
</dependency>

然后在user-service和order-service中的pom文件中引入nacos-discovery依赖:

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

2)配置nacos地址
在user-service和order-service的application.yml中添加nacos地址:

spring:
  cloud:
    nacos:
      server-addr: localhost:8848
  1. 启动
    重启微服务后,登录nacos管理页面,页面如下
    微服务技术栈2022-学习这一篇就够了_第27张图片
    4)总结
    微服务技术栈2022-学习这一篇就够了_第28张图片
1.5.2nacos服务多级存储模型

微服务技术栈2022-学习这一篇就够了_第29张图片
微服务技术栈2022-学习这一篇就够了_第30张图片
修改user-service的application.yml文件,添加集群配置:

spring:
  cloud:
    nacos:
      server-addr: localhost:8848
      discovery:
        cluster-name: HZ # 集群名称

我们再次复制一个user-service启动配置,添加属性:

-Dserver.port=8083 -Dspring.cloud.nacos.discovery.cluster-name=SH

微服务技术栈2022-学习这一篇就够了_第31张图片
结果:
微服务技术栈2022-学习这一篇就够了_第32张图片

微服务技术栈2022-学习这一篇就够了_第33张图片

1.5.3nacos同集群优先的负载均衡

1)给order-service配置集群信息
修改order-service的application.yml文件,添加集群配置:

spring:
  cloud:
    nacos:
      server-addr: localhost:8848
      discovery:
        cluster-name: HZ # 集群名称

2)修改负载均衡规则
修改order-service的application.yml文件,修改负载均衡规则:

userservice:
  ribbon:
    NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule # 负载均衡规则 
1.5.4nacos服务权重设置

微服务技术栈2022-学习这一篇就够了_第34张图片
微服务技术栈2022-学习这一篇就够了_第35张图片

1.5.5nacos环境隔离

微服务技术栈2022-学习这一篇就够了_第36张图片
微服务技术栈2022-学习这一篇就够了_第37张图片
微服务技术栈2022-学习这一篇就够了_第38张图片
微服务技术栈2022-学习这一篇就够了_第39张图片
微服务技术栈2022-学习这一篇就够了_第40张图片
微服务技术栈2022-学习这一篇就够了_第41张图片
Nacos的服务实例分为两种l类型:

  • 临时实例:如果实例宕机超过一定时间,会从服务列表剔除,默认的类型。

  • 非临时实例:如果实例宕机,不会从服务列表剔除,也可以叫永久实例。

配置一个服务实例为永久实例:

spring:
  cloud:
    nacos:
      discovery:
        ephemeral: false # 设置为非临时实例

微服务技术栈2022-学习这一篇就够了_第42张图片

1.6 Nacos配置管理

1.6.1 统一配置管理

微服务技术栈2022-学习这一篇就够了_第43张图片
步奏1) nacos控制台配置信息
微服务技术栈2022-学习这一篇就够了_第44张图片
微服务技术栈2022-学习这一篇就够了_第45张图片

命名一般是服务名称+“-”+环境名称+“.yaml”,保证唯一性
2)引入nacos-config依赖
首先,在user-service服务中,引入nacos-config的客户端依赖:

<!--nacos配置管理依赖-->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>

3)添加bootstrap.yaml
然后,在user-service中添加一个bootstrap.yaml(或yml)文件,bootstrap.yml的优先级比application.yml的优先级要高,内容如下:

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

微服务技术栈2022-学习这一篇就够了_第46张图片
4)代码测试

@Slf4j
@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private UserService userService;

    @Value("${pattern.dateformat}")
    private String dateformat;
    
    @GetMapping("now")
    public String now(){
        return LocalDateTime.now().format(DateTimeFormatter.ofPattern(dateformat));
    }
    // ...略
}

微服务技术栈2022-学习这一篇就够了_第47张图片

微服务技术栈2022-学习这一篇就够了_第48张图片

1.6.2 配置热更新

我们最终的目的,是修改nacos中的配置后,微服务中无需重启即可让配置生效,也就是配置热更新
要实现配置热更新,可以使用两种方式:
1)在@Value注入的变量所在类上添加注解@RefreshScope:
微服务技术栈2022-学习这一篇就够了_第49张图片

2)使用@ConfigurationProperties注解代替@Value注解。
微服务技术栈2022-学习这一篇就够了_第50张图片
微服务技术栈2022-学习这一篇就够了_第51张图片
微服务技术栈2022-学习这一篇就够了_第52张图片

1.6.3 配置共享

微服务技术栈2022-学习这一篇就够了_第53张图片
微服务技术栈2022-学习这一篇就够了_第54张图片

优先级:
微服务技术栈2022-学习这一篇就够了_第55张图片

1.6.4 搭建Nacos集群

微服务技术栈2022-学习这一篇就够了_第56张图片

1.7 Feign远程调用

1.7.1Feign代替RestTemplate远程调用

1)引入依赖

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

2)添加注解
在order-service的启动类添加注解@EnableFeignClients开启Feign的功能:
微服务技术栈2022-学习这一篇就够了_第57张图片
3)编写Feign的客户端
新建接口

package cn.itcast.order.client;

import cn.itcast.order.pojo.User;
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}")
    User findById(@PathVariable("id") Long id);
}

4)总结
微服务技术栈2022-学习这一篇就够了_第58张图片

1.7.2自定义配置

微服务技术栈2022-学习这一篇就够了_第59张图片
下面以日志为例来演示如何自定义配置。

1.7.2.1配置文件方式
feign:  
  client:
    config: 
      userservice: # 针对某个微服务的配置
        loggerLevel: FULL #  日志级别 

或针对所有服务

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

日志的级别分为四种:

  • NONE:不记录任何日志信息,这是默认值。
  • BASIC:仅记录请求的方法,URL以及响应状态码和执行时间
  • HEADERS:在BASIC的基础上,额外记录了请求和响应的头信息
  • FULL:记录所有请求和响应的明细,包括头信息、请求体、元数据。
1.7.2.2Java代码方式
public class DefaultFeignConfiguration  {
    @Bean
    public Logger.Level feignLogLevel(){
        return Logger.Level.BASIC; // 日志级别为BASIC
    }
}

微服务技术栈2022-学习这一篇就够了_第60张图片
微服务技术栈2022-学习这一篇就够了_第61张图片

1.7.3Feign使用优化

微服务技术栈2022-学习这一篇就够了_第62张图片
这里我们用Apache的HttpClient来演示。
1)引入依赖

在order-service的pom文件中引入Apache的HttpClient依赖:

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

2)配置连接池

在order-service的application.yml中添加配置:

feign:
  client:
    config:
      default: # default全局的配置
        loggerLevel: BASIC # 日志级别,BASIC就是基本的请求和响应信息
  httpclient:
    enabled: true # 开启feign对HttpClient的支持
    max-connections: 200 # 最大的连接数
    max-connections-per-route: 50 # 每个路径的最大连接数

1.7.4Feign最佳实践

微服务技术栈2022-学习这一篇就够了_第63张图片
微服务技术栈2022-学习这一篇就够了_第64张图片
微服务技术栈2022-学习这一篇就够了_第65张图片

1.7.5实现基于第二种 抽取的最佳实践

微服务技术栈2022-学习这一篇就够了_第66张图片
1)抽取
首先创建一个module,命名为feign-api:
微服务技术栈2022-学习这一篇就够了_第67张图片
微服务技术栈2022-学习这一篇就够了_第68张图片
在feign-api中然后引入feign的starter依赖

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

然后,order-service中编写的UserClient、User、DefaultFeignConfiguration都复制到feign-api项目中
微服务技术栈2022-学习这一篇就够了_第69张图片
2)在order-service中使用feign-api
首先,删除order-service中的UserClient、User、DefaultFeignConfiguration等类或接口。

在order-service的pom文件中中引入feign-api的依赖:

<dependency>
    <groupId>cn.itcast.demo</groupId>
    <artifactId>feign-api</artifactId>
    <version>1.0</version>
</dependency>

修改order-service中的所有与上述三个组件有关的导包部分,改成导入feign-api中的包

3)重启测试
发现报错
微服务技术栈2022-学习这一篇就够了_第70张图片
这是因为UserClient现在在cn.itcast.feign.clients包下,

而order-service的@EnableFeignClients注解是在cn.itcast.order包下,不在同一个包,无法扫描到UserClient。
4)解决扫描包问题
微服务技术栈2022-学习这一篇就够了_第71张图片
方式2较好
微服务技术栈2022-学习这一篇就够了_第72张图片

1.8 Gateway服务网关

1.8.1为什么需要网关

微服务技术栈2022-学习这一篇就够了_第73张图片
微服务技术栈2022-学习这一篇就够了_第74张图片
微服务技术栈2022-学习这一篇就够了_第75张图片

1.8.2gateway快速入门

1)创建gateway模块微服务技术栈2022-学习这一篇就够了_第76张图片
引入依赖

<!--网关-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<!--nacos服务发现依赖-->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

2)编写启动类
创建application.yml文件,内容如下:

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/开头就符合要求

本例中,我们将 /user/**开头的请求,代理到lb://userservice,lb是负载均衡,根据服务名拉取服务列表,实现负载均衡。

4)重启测试
微服务技术栈2022-学习这一篇就够了_第77张图片
5)流程
微服务技术栈2022-学习这一篇就够了_第78张图片
微服务技术栈2022-学习这一篇就够了_第79张图片

1.8.3gateway路由断言工厂

我们在配置文件中写的断言规则只是字符串,这些字符串会被Predicate Factory读取并处理,转变为路由判断的条件
例如Path=/user/**是按照路径匹配,这个规则是由
org.springframework.cloud.gateway.handler.predicate.PathRoutePredicateFactory类来处理的,像这样的断言工厂在SpringCloudGateway还有十几个:
微服务技术栈2022-学习这一篇就够了_第80张图片

1.8.4过滤器工厂

1)种类
官网:https://spring.io/projects/spring-cloud-gateway
微服务技术栈2022-学习这一篇就够了_第81张图片
2)请求头过滤器

spring:
  cloud:
    gateway:
      routes:
      - id: user-service 
        uri: lb://userservice 
        predicates: 
        - Path=/user/** 
        filters: # 过滤器
        - AddRequestHeader=Truth, Itcast is freaking awesome! # 添加请求头

3)默认过滤器-所有服务都生效

spring:
  cloud:
    gateway:
      routes:
      - id: user-service 
        uri: lb://userservice 
        predicates: 
        - Path=/user/**
      default-filters: # 默认过滤项
      - AddRequestHeader=Truth, Itcast is freaking awesome! 

4)总结
微服务技术栈2022-学习这一篇就够了_第82张图片

1.8.5全局过滤器

1)作用
全局过滤器的作用也是处理一切进入网关的请求和微服务响应,与GatewayFilter的作用一样。区别在于GatewayFilter通过配置定义,处理逻辑是固定的;而GlobalFilter的逻辑需要自己写代码实现。
定义方式是实现GlobalFilter接口。

public interface GlobalFilter {
    /**
     *  处理当前请求,有必要的话通过{@link GatewayFilterChain}将请求交给下一个过滤器处理
     *
     * @param exchange 请求上下文,里面可以获取Request、Response等信息
     * @param chain 用来把请求委托给下一个过滤器 
     * @return {@code Mono} 返回标示当前过滤器业务结束
     */
    Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain);
}

在filter中编写自定义逻辑,可以实现下列功能:

  • 登录状态判断
  • 权限校验
  • 请求限流等
    2)自定义全局过滤器
@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().setStatusCode(HttpStatus.FORBIDDEN);
        // 4.2.结束处理
        return exchange.getResponse().setComplete();
    }
}

微服务技术栈2022-学习这一篇就够了_第83张图片

1.8.6过滤器执行顺序

微服务技术栈2022-学习这一篇就够了_第84张图片

微服务技术栈2022-学习这一篇就够了_第85张图片

1.8.7跨域问题

跨域:域名不一致就是跨域,主要包括:

  • 域名不同: www.taobao.com 和 www.taobao.org 和 www.jd.com 和 miaosha.jd.com

  • 域名相同,端口不同:localhost:8080和localhost8081

跨域问题:浏览器禁止请求的发起者与服务端发生跨域ajax请求,请求被浏览器拦截的问题

常见报错:
在这里插入图片描述

解决方式:
在gateway服务的application.yml文件中,添加下面的配置:

spring:
  cloud:
    gateway:
      # 。。。
      globalcors: # 全局的跨域处理
        add-to-simple-url-handler-mapping: true # 解决options请求被拦截问题
        corsConfigurations:
          '[/**]':
            allowedOrigins: # 允许哪些网站的跨域请求 
              - "http://localhost:8090"
            allowedMethods: # 允许的跨域ajax的请求方式
              - "GET"
              - "POST"
              - "DELETE"
              - "PUT"
              - "OPTIONS"
            allowedHeaders: "*" # 允许在请求中携带的头信息
            allowCredentials: true # 是否允许携带cookie
            maxAge: 360000 # 这次跨域检测的有效期

微服务技术栈2022-学习这一篇就够了_第86张图片

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