-->
侧边栏壁纸
博主头像
断钩鱼 博主等级

行动起来,活在当下

  • 累计撰写 28 篇文章
  • 累计创建 34 个标签
  • 累计收到 0 条评论

目 录CONTENT

文章目录

OpenFeign 接入 SCA

halt
2021-12-12 / 0 评论 / 0 点赞 / 3194 阅读 / 0 字

OpenFeign 接入 SCA

参考:https://www.mengshuo.top/archives/springcloudnetflix#feign

demo地址:https://duangouyu.coding.net/p/demo/d/SCA/git/tree/openfeign

由于 Feign 也进入了维护, 所以就有了 OpenFeign 这个代替品

Feign 和 OpenFeign 的区别

FeignOpenFeign
Feign 是 Springcloud 组件中的一个轻量级 Restful 的 HTTP 服务客户端, Feign 内置了 Ribbon, 用来做客户端负载均衡, 去调用服务注册中心的服务. Feign 的使用方式是: 使用 Feign 的注解定义接口, 调用这个接口, 就可以调用服务注册中心的服务.OpenFeign 是 springcloud 在 Feign 的基础上支持了 SpringMVC 的注解, 如@RequestMapping 等等. OpenFeign 的@FeignClient 可以解析 SpringMVC 的@RequestMapping 注解下的接口, 并通过动态代理的方式产生实现类, 实现类中做负载均衡并调用其他服务.
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-feign</artifactId> </dependency><dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency>

OpenFeign 的使用:

微服务调用接口 + @FeignClient 注解

需要注意, @RequesMapping 不能在类名上与@FeignClient 同时使用

如果只有服务消费者添加配置就可以了,服务提供者不调用其他服务可以不用配置,因为底层毕竟还是发起 http 请求

整合 OpenFegin

添加依赖

<!-- 公共依赖 -->
<dependencies>
    <!-- 自定义异常处理 -->
    <dependency>
        <groupId>top.mengshuo</groupId>
        <artifactId>base-exception</artifactId>
    </dependency>
    <!-- 解决 bootstrap.yml 不生效问题  -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-bootstrap</artifactId>
    </dependency>
    <!-- web -->
    <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>
    <!--  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>
    <!-- base service -->
    <dependency>
        <groupId>top.mengshuo</groupId>
        <artifactId>base-service</artifactId>
    </dependency>
    <!-- open feign -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-openfeign</artifactId>
    </dependency>
    <!-- loadbalancer -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-loadbalancer</artifactId>
    </dependency>
    <!-- sentinel -->
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
    </dependency>
    <!-- nacos 持久化sentinel规则 -->
    <dependency>
        <groupId>com.alibaba.csp</groupId>
        <artifactId>sentinel-datasource-nacos</artifactId>
    </dependency>
    <!-- 测试 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
        <exclusions>
            <exclusion>
                <groupId>org.junit.vintage</groupId>
                <artifactId>junit-vintage-engine</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
</dependencies>

添加注解启用 OpenFeign

添加 @EnableFeignClients 注解

package top.mengshuo;

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

import java.util.Arrays;

/**
 * 服务消费者application
 *
 * @author mengshuo
 * @since 2021-11-17
 */
@EnableFeignClients
@EnableDiscoveryClient
@SpringBootApplication
public class ConsumerServiceApplication {
    public static void main(String[] args) {
        SpringApplication.run(ConsumerServiceApplication.class, args);
    }
}

配置文件启用 Sentinel 和 OpenFeign 的集成

# 启用 sentinel 和 openfeign 集成
feign:
  sentinel:
    enabled: true

代码

服务消费者

  1. 添加一个服务调用类

    package top.mengshuo.feign;
    
    import org.springframework.cloud.openfeign.FeignClient;
    import org.springframework.web.bind.annotation.PostMapping;
    import org.springframework.web.bind.annotation.RequestParam;
    import top.mengshuo.common.exception.entity.RestResponse;
    import top.mengshuo.feign.fallback.ProviderServiceFallback;
    
    /**
     * OpenFeign 声明式客户端
     *
     * @author mengshuo
     * @since 2021-12-12
     */
    @FeignClient(name = "provider-service", fallback = ProviderServiceFallback.class, path = "/provider")
    public interface ProviderService {
    
        /**
         * OpenFeign 调用服务提供者
         *
         * @param name 名称
         * @return res
         */
        @PostMapping("/hello")
        RestResponse<?> sayHello(@RequestParam("name") String name);
    }
    
  2. 服务降级类

    package top.mengshuo.feign.fallback;
    
    import org.springframework.stereotype.Component;
    import top.mengshuo.common.exception.entity.RestResponse;
    import top.mengshuo.feign.ProviderService;
    
    /**
     * @author mengshuo
     * @since 2021-11-23
     */
    @Component
    public class ProviderServiceFallback implements ProviderService {
    
        @Override
        public RestResponse<?> sayHello(String name) {
            return RestResponse.failed().message("OpenFeign 降级");
        }
    }
    
    
  3. Controller 中调用

    package top.mengshuo.controller;
    
    import lombok.extern.log4j.Log4j2;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    import top.mengshuo.common.exception.entity.RestResponse;
    import top.mengshuo.feign.ProviderService;
    
    import javax.annotation.Resource;
    import java.time.LocalDateTime;
    import java.time.format.DateTimeFormatter;
    
    /**
     * @author mengshuo
     * @since 2021-11-17
     */
    @Log4j2
    @RestController
    @RequestMapping("/consumer")
    public class ConsumerController {
    
    
        @Resource
        private ProviderService providerService;
    
        @GetMapping("/hello")
        public RestResponse<?> hello(String name) {
            log.info("处理时间:" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss:SS")));
            return this.providerService.sayHello(name);
        }
    
    }
    

服务提供者

  1. 添加 service

    package top.mengshuo.service.impl;
    
    import com.alibaba.csp.sentinel.annotation.SentinelResource;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.stereotype.Service;
    import top.mengshuo.service.ProviderService;
    
    /**
     * @author mengshuo
     * @since 2021-11-17
     */
    @SentinelResource
    @Service
    public class ProviderServiceImpl implements ProviderService {
    
        @Value("${sys.desc}")
        private String desc;
    
        /**
         * hello
         *
         * @param name name
         * @return res
         */
        @Override
        public String sayHello(String name) {
            return "hello:" + name + " >>> " + desc;
        }
    }
    
  2. 添加 Controller

    当没有 name 参数时 报错 触发服务降级

    package top.mengshuo.controller;
    
    import org.springframework.util.ObjectUtils;
    import org.springframework.web.bind.annotation.PostMapping;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    import top.mengshuo.common.exception.entity.RestResponse;
    import top.mengshuo.service.ProviderService;
    
    import javax.annotation.Resource;
    
    /**
     * @author mengshuo
     * @since 2021-12-12
     */
    @RestController
    @RequestMapping("/provider")
    public class ProviderController {
    
        @Resource
        private ProviderService providerService;
    
        @PostMapping("/hello")
        public RestResponse<?> sayHello(String name) {
    
            if (ObjectUtils.isEmpty(name)) {
                throw new RuntimeException();
            }
            return RestResponse.success().data(this.providerService.sayHello(name));
        }
    }
    

测试

  1. 正常调用

    正常调用

  2. 缺少参数的调用

    缺少参数的调用

0
博主关闭了所有页面的评论