日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當前位置:首頁 > 科技  > 軟件

解密Spring Cloud微服務調用:如何輕松獲取請求目標方的IP和端口

來源: 責編: 時間:2023-11-28 09:37:12 222觀看
導讀目的Spring Cloud 線上微服務實例都是2個起步,如果出問題后,在沒有ELK等日志分析平臺,如何確定調用到了目標服務的那個實例,以此來排查問題圖片效果可以看到服務有幾個實例是上線,并且最終調用了那個實例圖片考慮到Spring

目的

Spring Cloud 線上微服務實例都是2個起步,如果出問題后,在沒有ELK等日志分析平臺,如何確定調用到了目標服務的那個實例,以此來排查問題TPA28資訊網——每日最新資訊28at.com

圖片圖片TPA28資訊網——每日最新資訊28at.com

效果

可以看到服務有幾個實例是上線,并且最終調用了那個實例TPA28資訊網——每日最新資訊28at.com

圖片圖片TPA28資訊網——每日最新資訊28at.com

考慮到Spring Cloud在版本升級中使用了兩種負載均衡實現,Robin和LoadBalancer,下面我們提供兩種實現方案TPA28資訊網——每日最新資訊28at.com

Robin實現方案

1. 技術棧

  • Spring Cloud: Hoxton.SR6
  • Spring Boot: 2.3.1.RELEASE
  • Spring-Cloud-Openfeign: 2.2.3.RELEASE

2. 繼承RoundRobinRule,并重寫choose方法

/** * 因為調用目標機器的時候,如果目標機器本身假死或者調用目標不通無法數據返回,那么feign無法打印目標機器。這種場景下我們需要在調用失敗(目標機器沒有返回)的時候也能把目標機器的ip打印出來,這種場景需要我們切入feign選擇機器的邏輯,注入我們自己的調度策略(默認是roundrobin),在里面打印選擇的機器即可。*/@Slf4jpublic class FeignRule extends RoundRobinRule {    @Override    public Server choose(Object key) {        Server server = super.choose(key);        if (Objects.isNull(server)) {            log.info("server is null");            return null;        }        log.info("feign rule ---> serverName:{}, choose key:{}, final server ip:{}", server.getMetaInfo().getAppName(), key, server.getHostPort());        return server;    }    @Override    public Server choose(ILoadBalancer lb, Object key) {        Server chooseServer = super.choose(lb, key);        List<Server> reachableServers = lb.getReachableServers();        List<Server> allServers = lb.getAllServers();        int upCount = reachableServers.size();        int serverCount = allServers.size();        log.info("serverName:{} upCount:{}, serverCount:{}", Objects.nonNull(chooseServer) ? chooseServer.getMetaInfo().getAppName() : "", upCount, serverCount);        for (Server server : allServers) {            if (server instanceof DiscoveryEnabledServer) {                DiscoveryEnabledServer dServer = (DiscoveryEnabledServer) server;                InstanceInfo instanceInfo = dServer.getInstanceInfo();                if (instanceInfo != null) {                    InstanceInfo.InstanceStatus status = instanceInfo.getStatus();                    if (status != null) {                        log.info("serverName:{} server:{}, status:{}", server.getMetaInfo().getAppName(), server.getHostPort(), status);                    }                }            }        }        return chooseServer;    }}

3.修改RibbonClients配置

import org.springframework.cloudflix.ribbon.RibbonClients;import org.springframework.context.annotation.Configuration;/** * @description:feign 配置 */@Configuration@RibbonClients(defaultConfiguration = {FeignRule.class})public class FeignConfig {}

LoadBalancer實現方案

1. 技術棧

  • Spring Cloud: 2021.0.4
  • Spring Boot: 2.7.17
  • Spring-Cloud-Openfeign: 3.1.4

2. 繼承ReactorServiceInstanceLoadBalancer,并實現相關方法

@Slf4jpublic class CustomRoundRobinLoadBalancer implements ReactorServiceInstanceLoadBalancer {    final AtomicInteger position;    final String serviceId;    ObjectProvider<ServiceInstanceListSupplier> serviceInstanceListSupplierProvider;    public CustomRoundRobinLoadBalancer(ObjectProvider<ServiceInstanceListSupplier> serviceInstanceListSupplierProvider, String serviceId) {        this(serviceInstanceListSupplierProvider, serviceId, (new Random()).nextInt(1000));    }    public CustomRoundRobinLoadBalancer(ObjectProvider<ServiceInstanceListSupplier> serviceInstanceListSupplierProvider, String serviceId, int seedPosition) {        this.serviceId = serviceId;        this.serviceInstanceListSupplierProvider = serviceInstanceListSupplierProvider;        this.position = new AtomicInteger(seedPosition);    }    public Mono<Response<ServiceInstance>> choose(Request request) {        ServiceInstanceListSupplier supplier = this.serviceInstanceListSupplierProvider.getIfAvailable(NoopServiceInstanceListSupplier::new);        return supplier.get(request).next().map((serviceInstances) -> {            return this.processInstanceResponse(supplier, serviceInstances);        });    }    private Response<ServiceInstance> processInstanceResponse(ServiceInstanceListSupplier supplier, List<ServiceInstance> serviceInstances) {        Response<ServiceInstance> serviceInstanceResponse = this.getInstanceResponse(serviceInstances);        if (supplier instanceof SelectedInstanceCallback && serviceInstanceResponse.hasServer()) {            ((SelectedInstanceCallback)supplier).selectedServiceInstance((ServiceInstance)serviceInstanceResponse.getServer());        }        return serviceInstanceResponse;    }    private Response<ServiceInstance> getInstanceResponse(List<ServiceInstance> instances) {        if (instances.isEmpty()) {            if (log.isWarnEnabled()) {                log.warn("No servers available for service: " + this.serviceId);            }            return new EmptyResponse();        } else {            int pos = this.position.incrementAndGet() & Integer.MAX_VALUE;            ServiceInstance instance = instances.get(pos % instances.size());            log.info("serverName:{} upCount:{}",instance.getServiceId(),instances.size());            log.info("feign rule ---> serverName:{}, final server ip:{}:{}", instance.getServiceId(), instance.getHost(),instance.getPort());            return new DefaultResponse(instance);        }    }}

3.修改LoadBalancerClients配置

@Configuration@LoadBalancerClients(defaultConfiguration = CustomLoadBalancerConfiguration.class)public class CustomLoadBalancerConfig {}@Configurationclass CustomLoadBalancerConfiguration {    /**     * 參考默認實現     * @see org.springframework.cloud.loadbalancer.annotation.LoadBalancerClientConfiguration#reactorServiceInstanceLoadBalancer     * @return     */    @Bean    public ReactorLoadBalancer<ServiceInstance> reactorServiceInstanceLoadBalancer(Environment environment, LoadBalancerClientFactory loadBalancerClientFactory) {        String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);        return new CustomRoundRobinLoadBalancer(loadBalancerClientFactory.getLazyProvider(name, ServiceInstanceListSupplier.class), name);    }}

以上兩部完成大功告成!TPA28資訊網——每日最新資訊28at.com

源碼下載:https://github.com/dongweizhao/spring-cloud-example/tree/SR6-OpenFeign https://github.com/dongweizhao/spring-cloud-example/tree/EurekaOpenFeignTPA28資訊網——每日最新資訊28at.com

TPA28資訊網——每日最新資訊28at.com

本文鏈接:http://www.www897cc.com/showinfo-26-34679-0.html解密Spring Cloud微服務調用:如何輕松獲取請求目標方的IP和端口

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: 超高效,使用Terraform創建Docker鏡像和容器

下一篇: Javascript的閉包有哪些應用?你學會了嗎?

標簽:
  • 熱門焦點
  • 6月安卓手機性能榜:vivo/iQOO霸占旗艦排行榜前三

    2023年上半年已經正式過去了,我們也迎來了安兔兔V10版本,在新的驍龍8Gen3和天璣9300發布之前,性能榜的榜單大體會以驍龍8Gen2和天璣9200+為主,至于那顆3.36GHz的驍龍8Gen2領先
  • CSS單標簽實現轉轉logo

    轉轉品牌升級后更新了全新的Logo,今天我們用純CSS來實現轉轉的新Logo,為了有一定的挑戰性,這里我們只使用一個標簽實現,將最大化的使用CSS能力完成Logo的繪制與動畫效果。新logo
  • 十個簡單但很有用的Python裝飾器

    裝飾器(Decorators)是Python中一種強大而靈活的功能,用于修改或增強函數或類的行為。裝飾器本質上是一個函數,它接受另一個函數或類作為參數,并返回一個新的函數或類。它們通常用
  • 如何通過Python線程池實現異步編程?

    線程池的概念和基本原理線程池是一種并發處理機制,它可以在程序啟動時創建一組線程,并將它們置于等待任務的狀態。當任務到達時,線程池中的某個線程會被喚醒并執行任務,執行完任
  • 一個注解實現接口冪等,這樣才優雅!

    場景碼猿慢病云管理系統中其實高并發的場景不是很多,沒有必要每個接口都去考慮并發高的場景,比如添加住院患者的這個接口,具體的業務代碼就不貼了,業務偽代碼如下:圖片上述代碼有
  • 重估百度丨“晚熟”的百度云,能等到春天嗎?

    &copy;自象限原創作者|程心排版|王喻可2016年7月13日,百度云計算戰略發布會在北京舉行,宣告著百度智能云的正式啟程。彼時的會場座無虛席,甚至排隊排到了門外,在場的所有人幾乎都
  • 2天漲粉255萬,又一賽道在抖音爆火

    來源:運營研究社作者 | 張知白編輯 | 楊佩汶設計 | 晏談夢潔這個暑期,旅游賽道徹底火了:有的「地方」火了&mdash;&mdash;貴州村超旅游收入 1 個月超過 12 億;有的「博主」火了&m
  • 阿里瓴羊One推出背后,零售企業迎數字化新解

    作者:劉曠近年來隨著數字經濟的高速發展,各式各樣的SaaS應用服務更是層出不窮,但本質上SaaS大多局限于單一業務流層面,對用戶核心關切的增長問題等則沒有提供更好的解法。在Saa
  • OPPO K11采用全方位護眼屏:三大護眼能力減輕視覺疲勞

    日前OPPO官方宣布,全新的OPPO K11將于7月25日正式發布,將主打旗艦影像,和同檔位競品相比,其最大的賣點就是將配備索尼IMX890主攝,堪稱是2000檔位影像表
Top 主站蜘蛛池模板: 辰溪县| 十堰市| 商水县| 通河县| 朝阳区| 买车| 高州市| 依兰县| 崇左市| 冀州市| 文水县| 台中市| 恩平市| 云霄县| 定结县| 阳山县| 资中县| 丹东市| 平定县| 安阳市| 怀远县| 定安县| 广东省| 陇南市| 安福县| 休宁县| 德格县| 普洱| 德清县| 伽师县| 奈曼旗| 诸城市| 白朗县| 新宾| 太保市| 敦煌市| 墨竹工卡县| 连平县| 莱阳市| 天镇县| 苏尼特左旗|