Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >遗留非springboot传统项目接入eureka注册与服务发现

遗留非springboot传统项目接入eureka注册与服务发现

作者头像
vakinge
发布于 2023-02-22 07:22:36
发布于 2023-02-22 07:22:36
35200
代码可运行
举报
文章被收录于专栏:伯约架构思维伯约架构思维
运行总次数:0
代码可运行

推荐: jeesuite开发框架,免费开源、一站式解决方案。

最近规划自动化运维以及统一监控需求,鉴于目前公司内部大部分项目采用spring cloud体系架构、另外还有一些老的传统spring web的项目,于是就考虑把老的项目通过低成本改造的方式接入spring cloud体系,也就是可以通过eureka注册和服务发现、通过zuul服务路由

说干就干,通过eureka官方实例和研究spring boot注册eureka源码发现这个也很容易实现,所以废话不多说,直接贴代码了 。

首先加入项目依赖(maven为例)
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<dependency>
    <groupId>com.netflix.eureka</groupId>
    <artifactId>eureka-client</artifactId>
    <version>1.4.12</version>
    <exclusions>
        <exclusion>
          <groupId>javax.servlet</groupId>
          <artifactId>servlet-api</artifactId>
        </exclusion>
        <exclusion>
          <groupId>com.google.guava</groupId>
          <artifactId>guava</artifactId>
        </exclusion>
        <exclusion>
          <groupId>com.fasterxml.jackson.core</groupId>
          <artifactId>jackson-annotations</artifactId>
        </exclusion>
        <exclusion>
          <groupId>javax.ws.rs</groupId>
          <artifactId>jsr311-api</artifactId>
        </exclusion>
    </exclusions>
</dependency>

    <dependency>
      <groupId>com.netflix.archaius</groupId>
      <artifactId>archaius-core</artifactId>
      <version>0.7.4</version>
      <exclusions>
        <exclusion>
          <groupId>com.fasterxml.jackson.core</groupId>
          <artifactId>jackson-annotations</artifactId>
        </exclusion>
      </exclusions>
    </dependency>

    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-netflix-core</artifactId>
      <version>1.2.6.RELEASE</version>
      <exclusions>
        <exclusion>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-autoconfigure</artifactId>
        </exclusion>
      </exclusions>
    </dependency>
加入配置文件
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
eureka.region=default
eureka.registration.enabled=true
eureka.preferSameZone=true
eureka.shouldUseDns=false
eureka.serviceUrl.default=http://192.168.1.100:7861/eureka
eureka.decoderName=JacksonJson

eureka.name=demo
eureka.vipAddress=${eureka.name}-service
eureka.port=8081
eureka.homePageUrl=http://192.168.1.101:${eureka.port}
eureka.healthCheckUrl=http://192.168.1.101:${eureka.port}/service/health
eureka.statusPageUrl=http://192.168.1.101:${eureka.port}/service/info
  • spring.cloud.client.ipAddress :为自定义变量
  • healthCheckUrl,statusPageUrl接口可以不要,但是为了监控可以自己实现一个简单的接口即可
初始化eureka客户端
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
private void initEurekaClient() throws Exception{

        Properties properties = new Properties();

        InputStream inputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("eureka.properties");
        properties.load(inputStream);

        //
        properties.setProperty("eureka.ipAddr", IpUtils.getLocalIpAddr());
        instanceId = properties.getProperty("eureka.ipAddr") + ":" + properties.getProperty("eureka.ipAddr") + "/" + properties.getProperty("eureka.name");
        properties.setProperty("eureka.instanceId", instanceId);

        ConfigurationManager.loadProperties(properties);

        MyDataCenterInstanceConfig instanceConfig = new MyDataCenterInstanceConfig();
        InstanceInfo instanceInfo = new EurekaConfigBasedInstanceInfoProvider(instanceConfig).get();
        applicationInfoManager = new ApplicationInfoManager(instanceConfig, instanceInfo);

        DefaultEurekaClientConfig clientConfig = new DefaultEurekaClientConfig();

        eurekaClient = new DiscoveryClient(applicationInfoManager, clientConfig);

}
注册服务
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
private void waitForRegistrationWithEureka() {

        applicationInfoManager.setInstanceStatus(InstanceInfo.InstanceStatus.STARTING);
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
        }
        applicationInfoManager.setInstanceStatus(InstanceInfo.InstanceStatus.UP);

        long startTime = System.currentTimeMillis();
        //开启一个线程验证注册结果
        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    if (System.currentTimeMillis() - startTime > VERIFY_WAIT_MILLIS) {
                        log.warn(" >>>> service registration status not verify,please check it!!!!");
                        return;
                    }
                    try {
                        List<InstanceInfo> serverInfos = eurekaClient.getInstancesByVipAddress(vipAddress, false);
                        for (InstanceInfo nextServerInfo : serverInfos) {
                            if (nextServerInfo.getIPAddr().equals(IpUtils.LOCAL_BACK_IP)
                                    || nextServerInfo.getIPAddr().equals(IpUtils.getLocalIpAddr())) {
                                String instanceInfoJson = JsonUtils.getMapper().writerWithDefaultPrettyPrinter()
                                        .writeValueAsString(nextServerInfo);
                                log.info("verifying service registration with eureka finished,instance:\n{}",
                                        instanceInfoJson);
                                return;
                            }
                        }
                    } catch (Throwable e) {
                    }
                    try {
                        Thread.sleep(5000);
                    } catch (Exception e1) {
                    }
                    log.info("Waiting 5s... verifying service registration with eureka ...");
                }
            }
        }).start();
    }

通过这几步就完成了eureka的注册,登录eureka控制台你将能看到对应注册信息。但是在zuul转发调用过程发现一个问题:无法识别hostname,如果你们的服务器之间没有做hostname同步就需要继续改造,于是就看了下springboot注册eureka有一个配置项eureka.instance.preferIpAddress,所以我们也可以模仿他的实现。于是在初始化客户端的时候我们需要这样改造:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
MyDataCenterInstanceConfig instanceConfig = new MyDataCenterInstanceConfig(){
            @Override
            public String getHostName(boolean refresh) {
                String hostName = super.getHostName(refresh);
                if(ResourceUtils.getBoolean("eureka.preferIpAddress")){
                    hostName = IpUtils.getLocalIpAddr();
                }
                return hostName;
            }

            @Override
            public String getIpAddress() {
                return IpUtils.getLocalIpAddr();
            }

};

这样,注册的真实服务地址就是ip了。服务注册就搞定收工了。

接下来就是服务发现,及与其他springboot项目一样通过注册中心vipAddress互相调用。实际过程就是调用前去eureka拿一个真实地址替换vipAddress变量。

获取真实服务地址

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public String getRealServerHost(String serviceId){
    InstanceInfo serverInfo = eurekaClient.getNextServerFromEureka(serviceId, false);
    String realServerName = serverInfo.getIPAddr() + ":" + serverInfo.getPort();
    return realServerName;
}

下面是我实现的几个resttemplate

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class EurekaRestTemplateBuilder {

    private static Map<String, RestTemplate> restTemplates = new HashMap<>();

    public static synchronized RestTemplate build(ClientHttpRequestInterceptor ...interceptors ){
        return build("default", interceptors);
    }

    public static synchronized RestTemplate build(String name,ClientHttpRequestInterceptor ...interceptors ){

        if(restTemplates.containsKey(name))return restTemplates.get(name);

        SimpleClientHttpRequestFactory factory = new EurekaClientHttpRequestFactory();  
        factory.setReadTimeout(15000);//ms  
        factory.setConnectTimeout(5000);//ms 

        RestTemplate restTemplate = new RestTemplate(factory);
        List<ClientHttpRequestInterceptor> interceptorList = new ArrayList<>();
        interceptorList.add(new RestTemplateAutoHeaderInterceptor());
        if(interceptors != null && interceptors.length > 0){
            for (ClientHttpRequestInterceptor interceptor : interceptors) {
                interceptorList.add(interceptor);
            }
        }
        restTemplate.setInterceptors(interceptorList);
        //
        restTemplate.setErrorHandler(new CustomResponseErrorHandler());
        //
        restTemplates.put(name, restTemplate);

        return restTemplate;
    }

    private static class EurekaClientHttpRequestFactory extends SimpleClientHttpRequestFactory{

        @Override
        public ClientHttpRequest createRequest(URI uri, HttpMethod httpMethod) throws IOException {
            uri = convertToRealUri(uri);
            return super.createRequest(uri, httpMethod);
        }

        @Override
        public AsyncClientHttpRequest createAsyncRequest(URI uri, HttpMethod httpMethod) throws IOException {
            uri = convertToRealUri(uri);
            return super.createAsyncRequest(uri, httpMethod);
        }

        private URI convertToRealUri(URI uri){
            String serviceId = uri.getHost();
            try {               
                String realHost = EurekaRegistry.getInstance().getRealServerHost(serviceId);
                uri = new URI(uri.toString().replace(serviceId, realHost));
                return uri;
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }

    }
}

接下来就可以调用其他eureka注册服务了。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
private RestTemplate restTemplate = EurekaRestTemplateBuilder.build();

  public List<IdNamePair> getProvinces() {
    ParameterizedTypeReference<List<IdNamePair>> arearesponseType = new ParameterizedTypeReference<List<IdNamePair>>() {
    };
    List<IdNamePair> lists = restTemplate
        .exchange("http://DEMO-SERVICE/region/provinces", HttpMethod.GET, null, arearesponseType)
        .getBody();
    return lists;
  }
ZUUL转发配置
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
zuul.routes.demo.path=/demo/**
zuul.routes.demo.serviceId=demo-service

到此,服务注册和服务发现都完成了。 这里是一个demo

有任何问题,请加技术群:230192763讨论
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2017-12-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
【一起学源码-微服务】Nexflix Eureka 源码五:EurekaClient启动要经历哪些艰难险阻?
在源码分析三、四都有提及到EurekaClient启动的一些过程。因为EurekaServer在集群模式下 自己本身就是一个client,所以之前初始化eurekaServerContext就有涉及到eurekaClient的初始化。
一枝花算不算浪漫
2020/01/02
4430
SpringCloud组件:Eureka的服务发现与消费
在之前的章节我们已经把服务注册到Eureka Server,那么我们该怎么调用已经注册后的服务呢? 我们本章来简单的介绍我们具体该怎么调用服务节点请求内容。
恒宇少年
2018/10/10
1.1K0
领导“叕”让我研究 Eureka 源码:注册过程
Eureka Client 就是客户端,可以是 Eureka Server 自身,也可以是要注册的服务实例,比如订单服务、商品服务等。
悟空聊架构
2022/05/13
4070
领导“叕”让我研究 Eureka 源码:注册过程
Spring Cloud 快速上手之 Ribbon 负载均衡
Spring Cloud Ribbon是基于HTTP和TCP的客户端负载工具,它是基于Netflix Ribbon实现的。通过Spring Cloud的封装,可以轻松地将面向服务的REST 模板请求,自动转换成客户端负载均衡服务调用。提供云端负载均衡,有多种负载均衡策略可供选择,可配合服务发现和断路器使用。
架构探险之道
2020/05/17
7660
重学SpringCloud系列二之服务注册与发现---上
为了保障微服务的高可用,提供更高的并发能力,通常需要部署多份实现集群部署。为了快速的让大家入手Spring Cloud 微服务架构,此文只做简化版的服务注册中心的构建。后续我们会讲集群部署。
大忽悠爱学习
2022/05/07
9570
重学SpringCloud系列二之服务注册与发现---上
深入理解Ribbon之源码解析
方志朋
2017/12/29
1.3K0
深入理解Ribbon之源码解析
SpringCloud服务发现注册Eureka +Ribbon + Feign
假设有2个微服务A和B分别在端点http:// localhost:8181 /和http:// localhost:8282 /上运行,如果想要在A服务中调用B服务,那么我们需要在A服务中键入B服务的url,这个url是负载均衡器分配给我们的,包括负载平衡后的IP地址,那么很显然,B服务与这个URL硬编码耦合在一起了,如果我们使用了服务自动注册机制,就可以使用B服务的逻辑ID,而不是使用特定IP地址和端口号来调用服务。
慕容千语
2019/06/11
9500
服务注册与发现组件 Eureka 应用实战
在传统的单体应用中,组件之间的调用通过有规范约束的接口进行,实现不同模块间良好协作。在微服务架构中,原本的'巨石'应用按照业务被分割成相对独立的、提供特定功能的服务,每一个微服务都可以通过集群或者其他方式进行动态的扩展,每一个微服务实例的网络地址都可能动态变化,这使得原本通过硬编码地址的调用方式失去了适用性。微服务架构中,服务跨度之大,数量之多,迫切需要架构建立一个去中心化的组件对各个微服务实例的信息进行登记和管理,同时提供能力让各个服微务实例之间能够互相发现,从而达到互相调用的结果。
aoho求索
2019/08/21
5210
服务注册与发现组件 Eureka 应用实战
服务注册与发现组件 Eureka 客户端实现原理解析
在前面的文章介绍了,如何使用服务注册发现组件:Eureka,并给出使用示例。本文在此基础上,将会讲解 Eureka 客户端实现的内幕,结合源码深入实现的细节,知其所以然。客户端需要重点关注以下几点:
aoho求索
2019/09/25
2.3K0
服务注册与发现组件 Eureka 客户端实现原理解析
Spring Cloud(二):Eureka 服务注册中心
Spring Cloud Eureka 是基于 Netflix Eureka 来实现服务注册和发现的。它主要包括两个组件:
朝雾轻寒
2019/12/17
5390
Spring Cloud(二):Eureka 服务注册中心
聊聊eureka client的shutdown
spring-cloud-netflix-eureka-client-2.0.0.RC1-sources.jar!/org/springframework/cloud/netflix/eureka/EurekaClientAutoConfiguration.java
code4it
2018/09/17
2.4K0
《SpringCloud篇:001Eureka服务的注册与发现入门篇》
https://martinfowler.com/articles/microservices.html
2020/11/13
3340
《SpringCloud篇:001Eureka服务的注册与发现入门篇》
Eurkea,Ribbon和RestTemplate是如何结合到一起完成服务注册与发现功能的? --上
ResrTemplate组件是用来完成远程调用功能的,而Ribbon组件负责完成客户端负载均衡功能的,Eurkea服务端负责保存服务名和真实服务器地址的映射关系的,如果我们想要这三者结合起来完成服务发现与注册功能,有一个很简单的思路如下:
大忽悠爱学习
2023/02/13
6080
Eurkea,Ribbon和RestTemplate是如何结合到一起完成服务注册与发现功能的? --上
SpringCloudRibbon负载均衡实现原理
在SpringCloud中,我们最常使用到的负载均衡库就是ribbon。使用方式,一般是通过自动配置类注入,然后在类中定义负载均衡实例bean
tunsuy
2022/10/27
3240
Netflix时代之后Spring Cloud微服务的未来
如果有人会问你有关Spring Cloud的问题,那么你想到的第一件事可能就是Netflix OSS的支持。对Eureka,Zuul或Ribbon等工具的支持不仅由Spring提供,还由用于构建Apache Camel,Vert.x或Micronaut等微服务架构的其他流行框架提供。目前,Spring Cloud Netflix是Spring Cloud中最受欢迎的项目。它在GitHub上有大约3.2k的星星,而第二个最好的大约有1.4k。因此,Pivotal宣布大部分Spring Cloud Netflix模块正在进入维护模式,这是非常令人惊讶的。您可以通过Spencer Gibb https://spring.io/blog/2018/12/12/spring-cloud-greenwich-rc1-available-now 在Spring博客上发布的帖子中了解更多信息。好的,让我们对这些变化进行简短的总结。从Spring Cloud Greenwich发布开始Netflix OSS Archaius,Hystrix,Ribbon和Zuul正在进入维护模式。这意味着这些模块不会有任何新功能,Spring Cloud团队只会执行一些错误修复并修复安全问题。维护模式不包括仍支持的Eureka模块。对这些变化的解释非常简单。特别是其中两个。目前,Netflix并未积极开发Ribbon和Hystrix,尽管它们仍在大规模部署。此外,Hystrix已经被称为Atlas的遥测新解决方案所取代。Zuul的情况并不那么明显。Netflix已宣布于2018年5月开放Zuul 2。新版Zuul网关建立在Netty服务器之上,包括一些改进和新功能。您可以在Netflix博客https://medium.com/netflix-techblog/open-sourcing-zuul-2-82ea476cb2b3 上阅读更多相关信息。。尽管Netflix云团队做出了这一决定,但Spring Cloud团队已经放弃了Zuul模块的开发。我只能猜测它是由于早先决定在Spring Cloud系列中启动新模块而特别是因为它是基于微服务的架构中的API网关 - Spring Cloud Gateway。最后一块拼图是Eureka--一个发现服务器。它仍在发展,但这里的情况也很有趣。我将在本文的下一部分中对此进行描述。所有这些新闻激励我看一下Spring Cloud的现状,并讨论未来的一些潜在变化。作为掌握Spring Cloud的一本书的作者,我试图跟随该项目的演变以保持最新状态。还值得一提的是,我们的组织内部有微服务 - 当然是在Spring Boot和Spring Cloud之上构建的,使用Eureka,Zuul和Ribbon等模块。在本文中,我想讨论一些潜在的......对于诸如服务发现,分布式配置,客户端负载平衡和API网关等流行的微服务模式。
用户1516716
2019/05/07
8600
Netflix时代之后Spring Cloud微服务的未来
SpringCloud:Eureka服务注册与发现
Eureka 其实就是一个 服务注册与发现的中心,也就是相当于我们前面做的一些生产者的服务需要注册到我们的注册中心,那么我们的消费者就不用把代码写死,而是可以去服务中心订阅对应的服务,获取服务的最新地址,并且进行逻辑解耦。
lwen
2018/07/23
8830
SpringCloud框架搭建&Eureka&Ribbon&Feign&zull
是推出解决传统框架配置文件繁杂冗余,基于maven仓库和注解,快速搭建的框架,不依赖springcloud。
用户9919783
2022/07/29
3120
SpringCloud框架搭建&Eureka&Ribbon&Feign&zull
SpringCloud的入门学习之Eureka(高可用注册中心HA)构建Provider服务、Consumer服务
  使用springboot的多环境配置,来搭建Eureka的高可用集群式部署。由于使用的是maven构建的springboot项目,所以首先引入pom.xml配置文件,这里需要注意的是springboot的版本、springcloud的版本对应,不然会出现一个版本不对应错误,稍后可以贴一下错误。我使用的springboot版本是2.2.0的,springcloud版本是Hoxton.RC1。
别先生
2019/11/12
5880
Spring Cloud在Netflix后时代的走向?
如果有人问你关于Spring Cloud的问题,那么你首先想到的可能是Netflix OSS的支持。对Eureka,Zuul或Ribbon等工具的支持不仅由Spring提供,还可基于其他流行框架Apache Camel,Vert.x或Micronaut等构建微服务架构。
本人秃顶程序员
2019/04/16
2.7K0
Spring Cloud在Netflix后时代的走向?
SpringCloud详细教程 | 第一篇: 服务的注册与发现Eureka(Greenwich版本)
微服务是指开发一个单个小型的但有业务功能的服务,每个服务都有自己的处理和轻量通讯机制,简单的说就是对系统进行拆分,拆分多个服务,每个服务运行在其独立的进程中,服务和服务之间采用轻量级的通信机制相互沟通(通常是基于HTTP的Restful API).每个服务都围绕着具体的业务进行构建,并且能够被独立的部署到生产环境、类生产环境等
小东啊
2019/06/26
1.1K0
SpringCloud详细教程 | 第一篇: 服务的注册与发现Eureka(Greenwich版本)
推荐阅读
相关推荐
【一起学源码-微服务】Nexflix Eureka 源码五:EurekaClient启动要经历哪些艰难险阻?
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验