本文仅分享搭建过程,不涉及原理,以及各组件安装过程。
本文案例github地址:

https://github.com/ccccc-fm/SpringCloudAlibaba.git

搭建Nacos+openFeign

结构

module:alibabaConsumer   服务消费者,单机版
module:alibabaProvider8001   服务提供者,集群
module:alibabaProvider8002   服务提供者,集群
调用关系:消费者调用服务提供者

依赖
服务消费者

<dependencies>
        <!-- SpringCloud ailibaba nacos 与openFeign搭配时,排除ribbon-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.cloud</groupId>
                    <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <!--SpringCloud ailibaba sentinel -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
        </dependency>
        <!--open feign-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
        <!--  使用openFeign时通常搭配loadbalancer依赖一起  -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-loadbalancer</artifactId>
        </dependency>
    </dependencies>

服务提供者

 <!-- SpringCloud ailibaba nacos 与openFeign搭配时,排除ribbon-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.cloud</groupId>
                    <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

yml配置
消费者

server:
  port: 80
spring:
  application:
    name: alibaba-consumer
  cloud:
    nacos:
      discovery:
        server-addr: 47.111.229.5:8848
    sentinel:
      transport:
        dashboard: localhost:8080
        port: 8719
feign:
  sentinel:
    enabled: true

服务提供者

server:
  port: 8001
spring:
  application:
    name: alibaba-provider
  cloud:
    nacos:
      discovery:
        server-addr: 47.111.224.5:8848
feign:
  sentinel:
    enabled: true

启动类

消费者
@SpringBootApplication
@EnableFeignClients
@EnableDiscoveryClient
提供者
@SpringBootApplication
@EnableDiscoveryClient

代码

//引入服务提供者暴露的接口
@FeignClient(value ="alibaba-provider")
public interface ProviderService {

    @GetMapping(value = "/getInfo")
    public CommonResult getInfo();
}

//需要使用时,注入使用即可

Sentinel服务降级

在以上的基础上,添加Sentinel服务降级,本例的服务降级分为两种,一种是因程序内部异常引发的降级,另一种是请求未进入程序内部时的服务降级。第一张方法底层使用的依然是hystirx,第二种使用的是sentinel
结构

程序内部降级:
服务消费者consumer去调用provider8001与provider8002组成的集群时,使8001抛出异常
当consumer使用轮询算法访问到8001时,不能显示错误界面,而是显示服务降级方法所返回的页面
外部降级:
当/consuemr/getInfo每秒访问次数超过2次时,进行降级

依赖

内部降级
<dependency>
    <groupId>io.github.openfeign</groupId>
    <artifactId>feign-hystrix</artifactId>
    <version>11.0</version>
</dependency>
外部降级
引入sentinel,在上面已经引入了

yml配置
在搭建nacos+openFeign时已经写入sentinel的配置,本例中的服务降级在消费者端配置,所以服务提供者端不用配置Sentinel
启动类

启动类上的注解,使用注册中心时添加@EnableDiscoveryClient注解,使用openFeign时添加,@EnableFeignClients注解,启用分布式事务时要贴注解(可贴可不贴),一般就这几个注解

代码
程序内部异常降级

在openFeign接口上标注fallback类,这个类需要实现openFeign接口
@FeignClient(value = "alibaba-provider", fallback = ProviderServiceImpl.class)

创建实现类
@Component
public class ProviderServiceImpl implements ProviderService {

    @Override
    public CommonResult getInfo() {
        return CommonResult.success("服务器异常,请您稍后再试!");
    }
}

外部服务降级

1:在sentinel客户端中配置规则,本例配置流控规则
2:在需要降级的方法上贴注解@SentinelResource并指定降级方法
需要注意的是,降级方法要求与原方法返回值相同,方法用public static修饰,
方法参数与原方法相同并在最后添加一个BlockenException类型的参数,代码如下:
原方法:
    @GetMapping(value = "/consumer/getInfo")
    @SentinelResource(value = "info", blockHandlerClass = SentinelFallback.class, blockHandler = "streamLimit")
    public CommonResult getInfo() {
        CommonResult info = providerService.getInfo();
        return info;
    }
降级方法:
@Component
public class SentinelFallback {

    public static CommonResult streamLimit(BlockException blockHandler) {
        return CommonResult.success("当前访问人数较多,请稍后再试!");
    }
}

效果
程序内部异常降级,当80访问8001和8002时,访问8002正常,访问8001时返回降级方法
在这里插入图片描述
在这里插入图片描述
外部降级
在这里插入图片描述

添加gateway

依赖
注意:要移除spring-boot-start-web包
nacos要排除ribbon否则启动报错

    <dependencies>
        <!-- nacos-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.cloud</groupId>
                    <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>com.google.guava</groupId>
                    <artifactId>guava</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <!--gateway-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
        <!--热部署-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

yml配置文件

server:
  port: 9527

spring:
  application:
    name: cloud-gateway
  cloud:
    nacos:
      discovery:
        server-addr: 47.111.224.5:8848
    gateway:
      discovery:
        locator:
          enabled: true #开启从注册中心动态创建路由的功能,利用微服务名进行路由
      routes:
        - id: payment_routh
          uri: http://news.baidu.com
          predicates:
            - Path=/guonei
#这段配置的意思就是当访问localhost:9527/guonei时,跳转至http://news.baidu.com/guonei
#理解为将localhost:9527后面的内容,添加到uri后面,进行访问

gateway配置路由有两种方式,一种是上面的配置文件方式,另一个是程序方式,如下

@Configuration
public class GatewayConfiguration {

    @Bean
    public RouteLocator customRoute(RouteLocatorBuilder builder) {
        RouteLocatorBuilder.Builder route = builder.routes();
        route.route("path_baidu_guonei", r -> r.path("/consumer/getInfo").uri("http://localhost")).build();
        route.route("path_baidu_guonji", r -> r.path("/guoji").uri("http://news.baidu.com/guoji")).build();
        return route.build();
    }
}

访问效果图:
表面访问9527,实际返回的是访问80的结果
在这里插入图片描述

搭建RabbitMQ环境

1:依赖
2:配置文件
3:发送/接收消息

依赖
消息接收者和消息发送者依赖相同

    <dependencies>
        <!--stream rabbit -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-stream-rabbit</artifactId>
        </dependency>
        <!-- SpringCloud ailibaba nacos 与openFeign搭配时,排除ribbon-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.cloud</groupId>
                    <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <!-- 引用自己定义的api通用包 -->
        <dependency>
            <groupId>org.example</groupId>
            <artifactId>server-api-common</artifactId>
            <version>${project.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--监控-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <!--热部署-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

配置文件
发送者和接受者的配置不同,注意观察

消息发送者
server:
  port: 90

spring:
  application:
    name: cloud-rabbitmq-sendMsg
  cloud:
    stream:
      binders: # 在此处配置要绑定的rabbitmq的服务信息;
        defaultRabbit: # 表示定义的名称,用于于binding整合
          type: rabbit # 消息组件类型
          environment: # 设置rabbitmq的相关的环境配置
            spring:
              rabbitmq:
                host: 47.111.224.5
                port: 5672
                username: chen
                password: chenAdmin
      bindings: # 服务的整合处理
        output: # 这个名字是一个通道的名称
          destination: studyExchange # 表示要使用的Exchange名称定义
          content-type: application/json # 设置消息类型,本次为json,文本则设置“text/plain”
          default-binder: defaultRabbit # 设置要绑定的消息服务的具体设置
    nacos:
      discovery:
        server-addr: 47.111.224.5:8848

######消息接收者
server:
  port: 9001

spring:
  application:
    name: cloud-rabbitmq-receiveMsg
  cloud:
    stream:
      binders: # 在此处配置要绑定的rabbitmq的服务信息;
        defaultRabbit: # 表示定义的名称,用于于binding整合
          type: rabbit # 消息组件类型
          environment: # 设置rabbitmq的相关的环境配置
            spring:
              rabbitmq:
                host: 47.111.224.5
                port: 5672
                username: chen
                password: chenAdmin
      bindings: # 服务的整合处理
        input: # 这个名字是一个通道的名称
          destination: studyExchange # 表示要使用的Exchange名称定义
          content-type: application/json # 设置消息类型,本次为json,文本则设置“text/plain”
          default-binder: defaultRabbit # 设置要绑定的消息服务的具体设置
    nacos:
      discovery:
        server-addr: 47.111.224.5:8848

发送消息
用户主动调用接口发送消息

@EnableBinding(Source.class)
@Slf4j
public class SendMessageService {

    @Qualifier("output")
    @Autowired
    private MessageChannel channel;

    public String send() {
        String msg = UUID.randomUUID().toString();
        channel.send(MessageBuilder.withPayload(msg).build());
        log.info("消息生产者发送消息:" + msg);
        return msg;
    }
}

接收消息
监控消息管道后,自动接收消息

@Component
@EnableBinding(Sink.class)
@Slf4j
public class ReceiverMessage {

    @StreamListener(Sink.INPUT)
    public void input(Message<String> msg) {
        log.info("接收消息:" + msg.getPayload());
        System.out.println(msg.getPayload());
    }
}

效果图
在这里插入图片描述

在这里插入图片描述

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐