SpringCLoud_Aibaba
阅读原文时间:2023年07月09日阅读:1

微服务项目核心组件

https://gitee.com/gtnotgod/spring-cloud_-alibaba_-study001.git

  • 注册中心:nacos
  • API网关:gateway
  • 生产者-消费者之间的服务远程调用:openFeign
  • 服务容灾:Sentinel实现熔断和限流

Hystrix与Sentinel 的差别

Hystrix需要程序员手工搭建监控平台

Hystrix没有一套web界面可以给我们进行更细粒度化的配置

Sentinel 的主要特性

服务限流降级:默认支持 WebServlet、WebFlux, OpenFeign、RestTemplate、Spring Cloud Gateway, Zuul, Dubbo 和 RocketMQ 限流降级功能的接入,可以在运行时通过控制台实时修改限流降级规则,还支持查看限流降级 Metrics 监控。
服务注册与发现:适配 Spring Cloud 服务注册与发现标准,默认集成了 Ribbon 的支持。
分布式配置管理:支持分布式系统中的外部化配置,配置更改时自动刷新。
消息驱动能力:基于 Spring Cloud Stream 为微服务应用构建消息驱动能力。
分布式事务:使用 @GlobalTransactional 注解, 高效并且对业务零侵入地解决分布式事务问题。
阿里云对象存储:阿里云提供的海量、安全、低成本、高可靠的云存储服务。支持在任何应用、任何时间、任何地点存储和访问任意类型的数据。
分布式任务调度:提供秒级、精准、高可靠、高可用的定时(基于 Cron 表达式)任务调度服务。同时提供分布式的任务执行模型,如网格任务。网格任务支持海量子任务均匀分配到所有 Worker(schedulerx-client)上执行。
阿里云短信服务:覆盖全球的短信服务,友好、高效、智能的互联化通讯能力,帮助企业迅速搭建客户触达通道。

组件

  • Sentinel:把流量作为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。

  • Nacos:一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。

  • RocketMQ:一款开源的分布式消息系统,基于高可用分布式集群技术,提供低延时的、高可靠的消息发布与订阅服务。

  • Dubbo:Apache Dubbo 是一款高性能 Java RPC 框架。

  • Seata:阿里巴巴开源产品,一个易于使用的高性能微服务分布式事务解决方案。

  • Alibaba Cloud OSS: 阿里云对象存储服务(Object Storage Service,简称 OSS),是阿里云提供的海量、安全、低成本、高可靠的云存储服务。您可以在任何应用、任何时间、任何地点存储和访问任意类型的数据。

  • Alibaba Cloud SchedulerX: 阿里中间件团队开发的一款分布式任务调度产品,提供秒级、精准、高可靠、高可用的定时(基于 Cron 表达式)任务调度服务。

  • Alibaba Cloud SMS: 覆盖全球的短信服务,友好、高效、智能的互联化通讯能力,帮助企业迅速搭建客户触达通道。

简单的微服务项目搭建

父工程依赖:

<?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>com.gton</groupId>
    <artifactId>nacos</artifactId>
    <version>1.0-SNAPSHOT</version>
    <!--子模块-->
    <modules>
        <module>commons</module>
        <module>producer</module>
        <module>consumer</module>
        <module>gateway</module>
        <module>user_manager</module>
    </modules>
    <!--项目打包方式-->
    <packaging>pom</packaging>
    <!--Springboot父工程-->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.10.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <!--版本控制-->
    <properties>
        <java.version>1.8</java.version>
        <spring-cloud-alibaba.version>2.2.1.RELEASE</spring-cloud-alibaba.version>
        <spring-cloud.version>Hoxton.SR8</spring-cloud.version>
        <mall.version>1.0-SNAPSHOT</mall.version>
    </properties>

    <dependencyManagement>
        <!--自定义构建的公共模块-->
        <dependencies>
            <dependency>
                <groupId>com.gton</groupId>
                <artifactId>spring-cloud-gton-common</artifactId>
                <version>${mall.version}</version>
            </dependency>
            <!--Springcloud 依赖-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!--springcloud 阿里巴巴 依赖-->
            <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>
</project>

common:模块

<?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>nacos</artifactId>
        <groupId>com.gton</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <!--坐标-->
    <artifactId>spring-cloud-gton-common</artifactId>

<dependencies>

    <!--web项目驱动-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!--JWT鉴权-->
    <dependency>
        <groupId>io.jsonwebtoken</groupId>
        <artifactId>jjwt</artifactId>
        <version>0.9.0</version>
    </dependency>
    <!--        lombok-实体类简化依赖-->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.12</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>nacos</artifactId>
        <groupId>com.gton</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>producer</artifactId>

    <dependencies>

        <!--nacos服务发现-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>

        <!--web项目驱动-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!--feign远程调用:服务调用-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>

    </dependencies>

</project>

yml配置文件

server:
  port: 7001

spring:
  application:
    #服务自动发现并注册,不需要name
    name: start-provider
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848

logging:
  level:
    root: info
    org.springframework: info

生产者的服务

package com.gton.controller;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @program: springcloud-nacos
 * @description: 生产者的controller
 * @author: GuoTong
 * @create: 2020-11-20 10:51
 **/
@RestController
public class ProdcerController {

    /*日志*/
    private static  final Logger  logger = LoggerFactory.getLogger(ProdcerController.class);

    @GetMapping("/service")
    public String service(){
        logger.info("provider invoke");
        return "provider invoke";
    }
}

启动器

package com.gton;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;

/**
 * @program: springcloud-nacos
 * @description: 生产者启动类
 * @author: GuoTong
 * @create: 2020-11-20 10:57
 **/
@SpringBootApplication//springboot启动类
@EnableDiscoveryClient //服务发现客户端
@EnableFeignClients //feign 客户端,服务远程调用
public class ProducerApplication {

    public static void main(String[] args) {
        System.out.println("服务提供者启动成功");
        SpringApplication.run(ProducerApplication.class, args);
    }

}

消费者

<?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>nacos</artifactId>
        <groupId>com.gton</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>consumer</artifactId>

    <dependencies>

        <!--nacos服务发现-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>

        <!--web项目驱动-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!--feign远程调用:服务调用-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>

    </dependencies>

</project>

yml配置

server:
  port: 8001

spring:
  application:
    name: start-consumer
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848

logging:
  level:
    root: info
    org.springframework: info

远程调用接口

package com.gton.client;

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;

/**
 * @program: springcloud-nacos
 * @description: 新建feign客户端:生产者
 * @author: GuoTong
 * @create: 2020-11-20 11:13
 **/
/*远程调用哪个服务*/
@FeignClient(value = "start-provider")//生产者的微服务名
/**@FeignClient 调用服务的名称  yml配置文件的服务名*/
public interface ProducerClient {

    /**
     * 调用服务的方法
     * @return
     */
    @GetMapping("/service")
    public String service();
}

本地远程调用

package com.gton.controller;

import com.gton.client.ProducerClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @program: springcloud-nacos
 * @description: 消费者Controller
 * @author: GuoTong
 * @create: 2020-11-20 11:15
 **/
@RestController
public class ConsumerController {

    private static final Logger logger = LoggerFactory.getLogger(ConsumerController.class);

    /**
     * 动态代理对象,内部远程调用服务生产者
     */
    @Autowired
    private ProducerClient producerClient;

    @GetMapping("/service")
    public String service(){
        logger.info("consumer invoke");
        //远程调用
        String service = producerClient.service();
        return "comsumer invoke "+"|" + service;
    }
}

启动器

package com.gton;

import com.gton.controller.ConsumerController;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;

/**
 * @program: springcloud-nacos
 * @description: 消费者启动类
 * @author: GuoTong
 * @create: 2020-11-20 11:10
 **/
@SpringBootApplication
@EnableFeignClients//feign 远程调用客户端
@EnableDiscoveryClient//服务发现与注册到nacos
public class ConsumerApplication {
    private static final Logger logger = LoggerFactory.getLogger(ConsumerController.class);

    public static void main(String[] args) {

        logger.info("服务消费者启动成功");
        System.out.println("服务消费者启动成功");
        SpringApplication.run(ConsumerApplication.class, args);
    }
}

网关

网关路由配置:
#      routes: # 路由规则列表(列表)
#        - id: product-route # 路由规则ID
#          uri: lb://product-service # lb指的是从nacos中按照名称获取微服务,并遵循负载均衡策略
#          predicates: # 断言(判断某一个请求是否符合该路由规则)
#            - Path=/product-service/** # 只要请求路径中有/product-service/就符合该规则
#          filters: # 过滤器(对请求进行修改)
#            - StripPrefix=1 # 去掉请求路径的第一层

#        - id: order-route # 路由规则ID
#          uri: lb://order-service # lb指的是从nacos中按照名称获取微服务,并遵循负载均衡策略
#          predicates: # 断言(判断某一个请求是否符合该路由规则)
#            - Path=/order-service/** # 只要请求路径中有/product-service/就符合该规则
#          filters: # 过滤器(对请求进行修改)
#            - StripPrefix=1 # 去掉请求路径的第一层

如果不自定义路由列表,
那么`gateway`就发现只要按照`网关地址/微服务名称/接口`的格式去默认实现一个路由列表,

http://localhost:网关端口/微服务名称/Controller接口;默认规则
从而简化配置文件的书写。

Pom

<?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>nacos</artifactId>
        <groupId>com.gton</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>com.gton.gateway</artifactId>

    <dependencies>
        <!--springcloud第二代网关:gateway -->
        <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
        <!--Consider defining a bean of type 'org.springframework.http.codec.ServerCodecConfigurer' in your configuration.-->
       <!-- <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
            <exclusions>
                <exclusion>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </exclusion>
                 <exclusion>
                     <groupId>org.springframework.boot</groupId>
                     <artifactId>spring-boot-starter-webflux</artifactId>
                 </exclusion>
            </exclusions>&lt;!&ndash;&ndash;&gt;
        </dependency>-->
        <!-- nacos客户端 -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>

        <!--feign远程调用:服务调用-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>

   <!--     &lt;!&ndash;引入公共依赖:里面有JWT鉴权依赖,和工具类&ndash;&gt;
        <dependency>
            <groupId>com.gton</groupId>
            <artifactId>spring-cloud-gton-common</artifactId>
            <version>${mall.version}</version>
        </dependency>-->

        <!--JWT鉴权-->
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
            <version>0.9.0</version>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

yml配置文件

server:
  port: 10000
spring:
  application:
    name: api-gateway
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
    gateway:
      #      globalcors:
      #        cors-configurations:
      #          '[/**]':
      #            allowedOrigins: "*"
      #            allowedMethods: "*"
      discovery:
        locator:
          enabled: true # 让gateway可以发现nacos中的微服务
  redis:
    host: 127.0.0.1
#      routes: # 路由规则列表(列表)
#        - id: product-route # 路由规则ID
#          uri: lb://product-service # lb指的是从nacos中按照名称获取微服务,并遵循负载均衡策略
#          predicates: # 断言(判断某一个请求是否符合该路由规则)
#            - Path=/product-service/** # 只要请求路径中有/product-service/就符合该规则
#          filters: # 过滤器(对请求进行修改)
#            - StripPrefix=1 # 去掉请求路径的第一层
#        - id: order-route # 路由规则ID
#          uri: lb://order-service # lb指的是从nacos中按照名称获取微服务,并遵循负载均衡策略
#          predicates: # 断言(判断某一个请求是否符合该路由规则)
#            - Path=/order-service/** # 只要请求路径中有/product-service/就符合该规则
#          filters: # 过滤器(对请求进行修改)
#            - StripPrefix=1 # 去掉请求路径的第一层
logging:
  level:
    cn.edu.cque.mall: debug

启动器

package com.gton;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;

/**
 * @program: springcloud-nacos
 * @description: 网关入口
 * @author: GuoTong
 * @create: 2020-11-20 14:09
 **/
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients//原厂调用
public class GatewayApplication {

    public static void main(String[] args) {
        SpringApplication.run(GatewayApplication.class, args);
    }
}
......