聊聊不同集群的微服务如何通过feign调用

这篇具有很好参考价值的文章主要介绍了聊聊不同集群的微服务如何通过feign调用。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

之前业务部门的某项目微服务调用关系如下图

聊聊不同集群的微服务如何通过feign调用,微服务,java,数据库
后因业务改造需要,该项目需要将服务A部署到另外一个集群,但服务A仍然需要能调用到服务B,调用关系如下图
聊聊不同集群的微服务如何通过feign调用,微服务,java,数据库
之前调用方式是负责服务B的开发团队提供相应的feign客户端包给到服务A开发团队,服务A开发团队直接将客户端包引入到项目,在通过@EnableFeignClients来激活feign调用,现在跨了不同集群,而且2个集群间的注册中心也不一样,之前的调用方式就不大适用了。

业务部门的技术负责人就找到我们部门,看我们有没有什么方案。当时我们提供的方案,一种是服务A团队自己开发客户端接口去调用服务B,但这个方案工作量比较大。另外一种方案,就是通过改造openfeign。在业内一直很流行一句话,没有什么是加一层解决不了的

破局

后面我们提供的方案如下图

聊聊不同集群的微服务如何通过feign调用,微服务,java,数据库
本质上就是原来服务A直接调用服务B,现在是服务A先通过和服务B同集群的网关,间接调用服务B。思路已经有了,但是我们需要实现业务能够少改代码,就能实现该需求

实现思路

通过feign的url + gateway开启基于服务注册中心自动服务路由功能

改造步骤

1、自定义注解EnableLybGeekFeignClients

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Import(LybGeekFeignClientsRegistrar.class)
public @interface EnableLybGeekFeignClients {

    /**
     * Alias for the {@link #basePackages()} attribute. Allows for more concise annotation
     * declarations e.g.: {@code @ComponentScan("org.my.pkg")} instead of
     * {@code @ComponentScan(basePackages="org.my.pkg")}.
     * @return the array of 'basePackages'.
     */
    String[] value() default {};

    /**
     * Base packages to scan for annotated components.
     * <p>
     * {@link #value()} is an alias for (and mutually exclusive with) this attribute.
     * <p>
     * Use {@link #basePackageClasses()} for a type-safe alternative to String-based
     * package names.
     * @return the array of 'basePackages'.
     */
    String[] basePackages() default {};

    /**
     * Type-safe alternative to {@link #basePackages()} for specifying the packages to
     * scan for annotated components. The package of each class specified will be scanned.
     * <p>
     * Consider creating a special no-op marker class or interface in each package that
     * serves no purpose other than being referenced by this attribute.
     * @return the array of 'basePackageClasses'.
     */
    Class<?>[] basePackageClasses() default {};

    /**
     * A custom <code>@Configuration</code> for all feign clients. Can contain override
     * <code>@Bean</code> definition for the pieces that make up the client, for instance
     * {@link feign.codec.Decoder}, {@link feign.codec.Encoder}, {@link feign.Contract}.
     *
     * @return list of default configurations
     */
    Class<?>[] defaultConfiguration() default {};

    /**
     * List of classes annotated with @FeignClient. If not empty, disables classpath
     * scanning.
     * @return list of FeignClient classes
     */
    Class<?>[] clients() default {};
}

其实是照搬EnableFeignClients,差别只是import的bean不一样

2、扩展原生的FeignClientsRegistrar

扩展的核心内容如下

 @SneakyThrows
    private void registerFeignClient(BeanDefinitionRegistry registry,
                                     AnnotationMetadata annotationMetadata, Map<String, Object> attributes) {
        String className = annotationMetadata.getClassName();
        Class feignClientFactoryBeanClz = ClassUtils.forName("org.springframework.cloud.openfeign.FeignClientFactoryBean",Thread.currentThread().getContextClassLoader());
        String name = getName(attributes);
        String customUrl = getCustomUrl(getUrl(attributes),name);
        。。。省略其他代码
      
    }

    private String getCustomUrl(String url,String serviceName){
        if(StringUtils.hasText(url)){
            return url;
        }
        String gateWay = environment.getProperty("lybgeek.gateWayUrl");
        if(StringUtils.isEmpty(gateWay)){
            return url;
        }

        if(serviceName.startsWith("http://")){
            serviceName = StrUtil.trim(serviceName.replace("http://",""));
        }

        String customUrl = URLUtil.normalize(gateWay + "/" + serviceName);

        log.info("feign customed with new url:【{}】",customUrl);

        return customUrl;

    }

3、gateway开启基于服务注册中心自动服务路由功能

spring:
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true
          lower-case-service-id: true

测试

测试提供一个消费者、服务提供者、网关、注册中心

在消费者的启动类去掉原生的EnableFeignClients注解,采用我们自定义注解EnableLybGeekFeignClients

@SpringBootApplication
@EnableLybGeekFeignClients(basePackages = "com.github.lybgeek")
public class ConsumerApplication {
    public static void main(String[] args) {
        SpringApplication.run(ConsumerApplication.class);
    }

}

消费者application.yml开启feign调用日志

logging:
  level:
    # feign调用所在的包
    com.github.lybgeek.api.feign: debug


feign:
  client:
    config:
      default:
        # 开启feign记录请求和响应的标题、正文和元数据
        loggerLevel: FULL

通过消费端调用服务提供者
聊聊不同集群的微服务如何通过feign调用,微服务,java,数据库
可以正常访问,我们观察消费者控制台输出的信息

聊聊不同集群的微服务如何通过feign调用,微服务,java,数据库
我们可以发现,此次调用,是服务与服务之间的调用,说明我们扩展的feign保留了原本feign的能力

我们对消费者的application.yml,新增如下内容

lybgeek:
  gateWayUrl: localhost:8000

再通过消费端调用服务提供者

聊聊不同集群的微服务如何通过feign调用,微服务,java,数据库
可以正常访问,我们观察消费者控制台输出的信息
聊聊不同集群的微服务如何通过feign调用,微服务,java,数据库
同时观察网关控制台输出的信息
聊聊不同集群的微服务如何通过feign调用,微服务,java,数据库
我们可以发现,此次调用,是通过网关路由到服务再产生调用,说明我们扩展的feign已经具备通过网关请求服务的能力

总结

可能有朋友会说,何必这么麻烦扩展,直接通过

@FeignClient(name = "${feign.instance.svc:provider}",url="${lybgeek.gateWayUrl: }/${feign.instance.svc:provider}",path = InstanceServiceFeign.PATH,contextId = "instance")

不也可以实现。其实如果带入当时的业务场景考虑,就会发现这种方式,需要改的地方比直接扩展feign多得多,而且一旦出问题,不好集中回滚。有时候脱离业务场景,去谈论技术实现,会容易走偏

demo链接

https://github.com/lyb-geek/springboot-cloud-metadata-ext文章来源地址https://www.toymoban.com/news/detail-535094.html

到了这里,关于聊聊不同集群的微服务如何通过feign调用的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Http远程调用(feign客户端通过POST传递FORM格式数据)

    目录       feign实现http远程调用(正文)       解决方案: 在正式讲解HTTP远程调用时,我们先来了解一下缺省方法的定义。 写在前面: 缺省参数可传可不传,可以传多个但他们必须是相同的类型 每个方法中缺省参数只能定义一个,并且只能在参数的最后定义; 缺省参

    2023年04月08日
    浏览(28)
  • 微服务远程调用Feign

    目录 RPC概述 什么是Feign? RibbonFeign对比 Feign的设计架构 Spring Cloud Alibaba快速整合Feign Spring Cloud Feign扩展 日志配置 契约配置 通过拦截器实现参数传递 自定义拦截器实现认证逻辑 超时时间配置 微服务之间如何方便优雅的实现服务间的远程调用? RPC 全称是 Remote Procedure Call ,

    2024年03月14日
    浏览(30)
  • 【微服务】Feign远程调用

           📝个人主页: 五敷有你         🔥系列专栏: 微服务 ⛺️稳中求进,晒太阳 先来看我们以前利用RestTemplate发起远程调用的代码: 存在下面的问题: 代码可读性差,编程体验不统一 参数复杂URL难以维护 Feign是一个声明式的http客户端,官方地址:GitHub - OpenF

    2024年03月28日
    浏览(32)
  • 服务调用---------Ribbon和Feign

    目录 ​​​​​​​ 1、Ribbon 1.1 Ribbon简介 1.2 Ribbon负载均衡 负载均衡原理 负载均衡策略 Ribbon和Nginx的区别 1.3 服务调用和Ribbon负载均衡实现 2、FeignopenFeign 3、Feign支持的配置 日志功能  连接池  feign-api远程包 1.1 Ribbon简介 Ribbon是一个用于 客户端负载均衡的组件 ,它是Netfl

    2024年02月14日
    浏览(23)
  • 服务调用Ribbon,LoadBalance,Feign

    服务调用Ribbon、Fegin Ribbon实现负载均衡的原理 1:LoadBalancerAutoConfiguration这个类,这个类主要做的就是把LoadBalancer拦截器封装到RestTemplte拦截器集合里面去。 2:然后在代码里面调用restTemplate.getForObject或者其他方法的时候,就会调用到这个拦截器。 3:在LoadBalancer拦截器类中,

    2024年01月22日
    浏览(29)
  • 【微服务】SpringCloud之Feign远程调用

    🏡浩泽学编程 :个人主页  🔥 推荐专栏 :《深入浅出SpringBoot》《java对AI的调用开发》               《RabbitMQ》《Spring》《SpringMVC》《项目实战》 🛸学无止境,不骄不躁,知行合一 使用Feign远程调用代替RestTemplate远程调用。 使用RestTemplate发起远程调用: 虽然在引

    2024年04月15日
    浏览(20)
  • 微服务服务间调用组件Feign使用介绍、原理、优化技巧

    Feign是一个声明式的Web Service客户端。它让微服务之间的调用变得更简单。Feign具有可插拔式的注解支持,包括Feign 注解和JAX-RS注解。Feign还支持可插拔的编码器和解码器。Spring Cloud增加了对Spring MVC注解的支持,并且也支持Spring WebFlux。 Feign可以与Eureka和Ribbon组合使用以支持负载均

    2024年02月06日
    浏览(63)
  • 如何通过nginx反向代理实现不同域名映射到同一台服务器的相同端口

    要在Nginx中实现不同域名映射到同一台服务器的相同端口,您可以使用Nginx的代理转发技术。 首先,您需要了解Nginx的代理转发工作原理。Nginx的代理转发是指在代理服务器(proxy server)收到一个请求时,先将请求转发给目标服务器(target server),然后将服务器的响应返回给代

    2024年02月13日
    浏览(45)
  • feign自定义第三方接口;配置化Feign接口URL;调用指定IP的feign服务

    最近接手一个项目,各子工程之间通过feign调用;各服务部署在K8S上,通过nacos管理配置;由于服务部署的机器无法开放端口等原因,导致本机服务与测试环境网络端口无法互通,故需要重写feign的调用地址;个人总结的方法有以下几种: 目录  第一种:feignclient配置URL 第二种

    2024年02月04日
    浏览(45)
  • SpringCloud微服务环境中,使用Feign跨服务调用Api

    在微服务中,很多时候都需要调用其他小组的服务接口,这里记录一下使用Feign调用其他服务的过程。 第一步,导入依赖:  第二步,被调用服务编写接口:  第三步,调用服务端启动类上添加@EnableFeignClients  第四步,编写调用API接口,接口上添加@FeignClient注解,注解的na

    2024年02月10日
    浏览(23)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包