当前位置: 首页 > article >正文

Java学习Day60:微服务总结!(有经处无火,无火处无经)

1、技术版本

jdk:17及以上

-如果JDK8

springboot:3.1及其以上

-版本2.x

springFramWork:6.0及其以上

-版本5.x

springCloud:2022.0.5

-版本格林威治或者休斯顿

2、模拟springcloud

父模块指定父pom

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

配置provider的application.yml

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/db2
    username: root
    password: 123456
  application:
    name: providerServer
mybatis:
  type-aliases-package: com.home.pojo
  configuration:
        log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

server:
  port: 8088

provider实现controller层,services层,和Mapper层,pojo

provider的pom

<properties>
    <spring-cloud.version>2022.0.5</spring-cloud.version>
<properties>

spring-boot-starter-web
mysql-connector-j
lombok
mybatis-spring-boot-starter
mybatis-plus-spring-boot3-starter

<dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
</dependencyManagement>

consumr层只用实现controller层和pojo

consumer的application.yml

server:
  port: 8080
spring:
  application:
    name: consumer

pom

<properties>
   <spring-cloud.version>2022.0.5</spring-cloud.version>
<properties>

spring-boot-starter-web
lombok


<!--SpringCloud,BOM,依赖清单导入,所有依赖管理的坐标-->
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

consumer调用provider的方法

usersss userssses= restTemplate.getForObject("http://localhost:8088/user/findAll",usersss.class);
return userssses;

访问consumer即可调用provider的方法

思考:

1.硬URL的端口号(端口变化,服务宕机

2.负载均衡无法实现

3.无返回信息

4.优化RestTemplate

5.多服务权限拦截如何实现?怎么保证所有微服务服务的安全性?

6.优化众多微服务的配置文件

3.注册中心eureka

Eureka服务器:

pom

<properties>
        <spring-cloud.version>2022.0.5</spring-cloud.version>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>eureka_server</artifactId>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>
    </dependencies>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

application.yml

#启动服务器端口
server:
  port: 8761
#应用程序名字
spring:
  application:
    name: eurekaServer
#EurekaServer的地址,现在是自己的地址,如果是集群,需要写其它Server的地址。
eureka:
  client:
   fetch-registry: false
   register-with-eureka: false
  service-url:
   defaultZone: http://127.0.0.1:8761/eureka

启动类中标志:@EnableEurekaServer

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

Eureka服务端组件:

在服务提供者provider_service工程中添加Eureka客户端依赖


  <!--eureka客户端starter-->
  <dependencies>
      <dependency>
          <groupId>org.springframework.cloud</groupId>
          <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
      </dependency>
  </dependencies>
  <!--SpringCloud,BOM,依赖清单导入,所有依赖管理的坐标-->
  <dependencyManagement>
          <dependencies>
              <dependency>
                  <groupId>org.springframework.cloud</groupId>
                  <artifactId>spring-cloud-dependencies</artifactId>
                  <version>${spring-cloud.version}</version>
                  <type>pom</type>
                  <scope>import</scope>
              </dependency>
          </dependencies>
  </dependencyManagement>

在启动类上开启Eureka客户端发现功能@EnableDiscoveryClient

@SpringBootApplication
@EnableDiscoveryClient // 开启Eureka客户端发现功能
public class UserApplication {
    public static void main(String[] args) {
        SpringApplication.run(UserApplication.class,args);
    }
}

注册到注册中心

修改配置文件:spring.application.name指定应用名称,作为服务ID使用

server:
  port: 8088
#配置eureka注册中心的地址
# 注册中心地址
eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:8761/eureka
# 租约续约间隔时间,默认30秒
  eureka:
    instance:
      lease-renewal-interval-in-seconds: 30

Eureka客户端组件

在服务消费者consumer_service工程中添加Eureka客户端依赖

<!-- Eureka客户端 -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!--SpringCloud所有依赖管理的坐标-->
<dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
</dependencyManagement>

注册到注册中心

# 注册中心地址
eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:8761/eureka
    registry-fetch-interval-seconds: 30

在启动类开启Eureka客户端@EnableDiscoveryClient

@SpringBootApplication
@EnableDiscoveryClient
public class springBootConsumerStarter {
    public static void main(String[] args) {
        SpringApplication.run(springBootConsumerStarter.class,args);
    }
    @Bean
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
}

配置完成后执行流程

  1. 通过注册中心客户端对象DiscoveryClient,获取Eureka中注册的user-service实例列表

  2. 获取user-service服务实例对象

  3. 从实例对象中获取host地址和端口,拼接请求地址

  4. 使用RestTemplate发送请求

public usersss findAll(){
         //discoveryClient 可以拉取注册中心中服务列表
        //getInstances(服务名),当前服务只有1个,返回值是List集合,获取0索引服务对象
   ServiceInstance instance = discoveryClient.getInstances("PROVIDERSERVER").get(0);
        //instance服务对象的实例。获取服务提供者的IP,端口号
   String host = instance.getHost();
   int port = instance.getPort();
   return restTemplate.getForObject("http://"+host+":"+port+"/user/findAll",usersss.class);
    }
}

4.Nacos

相比于erueka

Nacos消费者配置:
<properties>

     <spring.cloud.alibaba.version>2022.0.0.0</spring.cloud.alibaba.version>

<properties>

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

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


    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <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>
        </dependencies>
    </dependencyManagement>

配置Nacos注册中心地址

server:
  port: 8080
spring:
  application:
    name: consumerNacos
# 注册中心地址
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
Nacos服务端配置:
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
      <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
      </dependency>


    <!--SpringCloud,BOM,依赖清单导入,所有依赖管理的坐标-->
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>


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


        </dependencies>
    </dependencyManagement>

application.yml不变

负载均衡:

在consumer中配置即可

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

在启动类配置

    @LoadBalanced
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
问题:需要编写类似的大量重复代码,格式基本相同,无非参数不一样!

5.OpenFeign

Feign 的英文表意为“假装,伪装,变形”, 是一个http请求调用的轻量级框架,是以Java接口的方式发送Http请求,而不用像Java中通过封装HTTP请求url的方式直接调用。Feign通过处理注解,将请求模板化,当实际调用的时候,传入参数,根据参数再应用到请求上,进而转化成真正的请求,这种请求相对而言比较直观。

Feign被广泛应用在Spring Cloud 的解决方案中,是学习基于Spring Cloud 微服务架构不可或缺的重要组件。

需要导入:

        <!--伪装调用jar-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>

启动引导类加@EnableFeignClients注解

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

编写FeignClient接口,使用SpringMVC的注解

@FeignClient("providerUser")
public interface FeignUserService {
    @RequestMapping("feign/eignQueryUserById")
    User feignQueryUserById(@RequestParam("id") Integer id);
}

在Controller中注入Feign接口,直接调用,无需实现类,但是GetMaping的Restful风格必去和调用provider的方法相同且传参方式也相同!!!

访问接口测试!

支持熔断(服务降级)、配置日志级别、请求压缩和响应压缩

6.网关GateWay

所有微服务的统一入口。Spring Cloud Gateway 是 Spring Cloud 的一个全新项目,该项目是基于 Spring 5.0,Spring Boot 2.0 和 Project Reactor 等技术开发的网关,它旨在为微服务架构提供一种简单有效的统一的 API 路由管理方式。

  • Route(路由):这是网关的基本模块。它由一个 ID,一个目标 URI,一组断言和一组过滤器定义。如果断言为真,则路由匹配。

  • Predicate(断言):这是一个 Java 8 的 Predicate。输入类型是一个 ServerWebExchange。我们可以使用它来匹配来自 HTTP 请求的任何内容,例如 headers 或参数。

  • Filter(过滤器):这是org.springframework.cloud.gateway.filter.GatewayFilter的实例,我们可以使用它修改请求和响应。

创建SpringBoot工程gateway_server

  <!--引入网关的jar包,不能引web jar包-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>

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


        <!--负载均衡-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-loadbalancer</artifactId>
        </dependency>

        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
            <version>0.7.0</version>
        </dependency>
        <dependency>
            <groupId>javax.xml.bind</groupId>
            <artifactId>jaxb-api</artifactId>
            <version>2.3.1</version>
        </dependency>
    </dependencies>


    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <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>
        </dependencies>
    </dependencyManagement>

application.yml

定义端口号,名称,注册到nacos

这是为当前路由规则指定一个 唯一的标识符

  • lb:// 是 负载均衡(Load Balancer)的前缀,意味着请求将通过负载均衡机制路由到一个注册在 Eureka、Consul 或其他注册中心的服务。
  • consumerOpenFeign 是服务的名称,这个名称需要与注册中心中服务的名称一致。Spring Cloud Gateway 会从服务注册中心获取该服务的实际地址(例如:http://consumerOpenFeign:8080),并且通过负载均衡器将请求转发到该服务。

predicates 用于定义请求的 匹配条件,即哪些请求应该由当前的路由规则来处理。在这个例子中,使用了 Path=/**,表示匹配所有的路径。

过滤器隐藏usertwo,访问时不用书写,避免接口地址暴露

server:
  port: 80
spring:
  application:
    name: gateway
  cloud:
    nacos:
      server-addr: 127.0.0.1:8848
    #配置网关
    gateway:
      routes:
        - id: orderService  #自定义路由的唯一标识符
          uri: lb://consumerOpenFeign  #服务名字,从注册中心通过服务名称来获取接口
          predicates:
            - Path=/**  #拦截浏览器的请求地址
          filters:
            - PrefixPath=/usertwo
自定义全局过滤器【重点】

token:登录成功后,根据登录用户名等(用户ID),生成一个属于这个用户自己的密钥,就称为Token。下次用户访问的时候,带着Token来请求服务器。拿Token值反解析出用户数据来(无论是解析失败,还是根本就没有Token)拦截器不能放行。登录成功的时候,产生一个加密后字符串:Token响应回浏览器的响应头。浏览器再次请求的时候,携带Token来访问服务器,Token会放在浏览器的请求头中。

大部分都是异步请求,axios拦截器

响应的时候,获取响应头中的token值。请求的时候,在请求头中添加token值。

token值存储在浏览器的缓存中,缓存对象 localStorage, setItem存储键值对,getItem传递键获取值

nacos注册和配置中心

nacos单独组件,启动就可以了,默认端口8848

微服务配置nacos注册中心的地址

spring:
  cloud:
    nacos:
      server-addr: 127.0.0.1:8848
sentinel流量防卫兵
        <!--熔断的支持-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-circuitbreaker-resilience4j</artifactId>
        </dependency>
        <!--配置哨兵-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
        </dependency>

配置文件

server:
  port: 8080
spring:
  application:
    name: consumerOpenFeign
  cloud:
    #哨兵
    sentinel:
      transport:
        dashboard: 127.0.0.1:8086
    nacos:
      server-addr: 127.0.0.1:8848
    openfeign:
      #feign熔断支持
      circuitbreaker:
          enabled: true

在方法上定义哨兵

    @GetMapping("/selectusertwo")
    @SentinelResource(value = "selectusertwo",
            fallback ="selectusertwoFallBack",
            blockHandler = "selectusertwoHandler")
    public usersss selectusertwo(@RequestParam("id") Integer id){
        if (id<4){
            throw new RuntimeException("请输入正确ID!");
        }
        return userServicesTwo.selectusertwo(id);
    }

fallback:限流

blockHandler:熔断


http://www.kler.cn/a/382510.html

相关文章:

  • CST汽车天线仿真(双向混合求解)
  • 掌握歌词用词技巧:写歌词的方法与艺术表达,妙笔生词AI智能写歌词软件
  • #渗透测试#SRC漏洞挖掘#XSS跨站脚本介绍02绕过
  • C++ 之boost/date_time/posix_time高精度计时详细总结
  • 微前端应用+MicApp、无界、乾坤、EMP+简要了解+部分场景应用
  • Caffeine 手动策略缓存 put() 方法源码解析
  • 栈的算法题 —— 有效的括号(LeetCode)
  • Java | Leetcode Java题解之第539题最小时间差
  • Python 自动化运维:安全与合规最佳实践
  • go 包管理
  • 进程和线程概念
  • Transformer究竟是什么?预训练又指什么?BERT
  • 查看 Active NameNode 的服务 ID
  • TryHackMe | Active Directory Basics
  • 2024中国自动化大会(CAC2024)“智慧化工及复合人才培养”平行会议圆满落幕
  • 50. Pow(x, n)
  • android——jetpack startup初始化框架
  • 区别:矩阵合同和矩阵酉相似
  • Android15音频进阶之Cuttlefish搭建音频开发环境(九十二)
  • 了解数据库并发产生的问题
  • Claude发布桌面客户端!新功能支持分析100页PDF的图像!
  • 知识课堂——高匿ip在不同业务中的重要作用
  • 蓝桥杯真题——乐乐的序列和(C语言)
  • 每日算法一练:剑指offer——字符串篇(2)
  • Lua 怎么解决闭包内存泄漏问题
  • 【Java算法】分治--归并排序