基于Eureka的Spring Cloud微服务治理框架

基于Eureka的Spring Cloud微服务治理框架

框架调用关系说明:

服务生产者启动时,向服务注册中心注册自己提供的服务

服务消费者启动时,在服务注册中心订阅自己所需要的服务

注册中心返回服务提供者的地址信息个消费者

消费者从提供者中调用服务

1. 服务注册与发现

1.1 Eureka简介

微服务之间一般需要相互调用,如果使用硬编码或者配置式,会存在一些问题:

  • 适用场景有限:如果网络地址变更,则需要修改配置并重新发布。
  • 无法动态伸缩:生产环境中,每个微服务一般都会部署多个实例,从而实现容灾和负载均衡。在微服务架构中,还可能需要动态增减节点。硬编码或者配置都无法实现这种需求。

服务发现组件具备以下功能:

  • 服务注册表:记录各个微服务的信息。
  • 服务注册与发现:服务注册是指微服务启动时,讲自己的信息注册到服务发现组件的过程;服务发现是指查询可用微服务列表及其网络地址的机制。
  • 服务检查:服务发现组件使用一定机制定时检测已注册的服务,如发现某实例长时间无法访问,就会从服务注册中移除该实例。

Eureka是Spring Cloud Netflix微服务套件中的一部分,可以与Spring Boot构建的微服务很容易的整合起来。

Eureka包含了服务器端和客户端组件。服务器端,也被称作是服务注册中心,用于提供服务的注册与发现。Eureka支持高可用的配置,当集群中有分片出现故障时,Eureka就会转入自动保护模式,它允许分片故障期间继续提供服务的发现和注册,当故障分片恢复正常时,集群中其他分片会把他们的状态再次同步回来。
客户端组件包含服务消费者与服务生产者。在应用程序运行时,Eureka客户端向注册中心注册自身提供的服务并周期性的发送心跳来更新它的服务租约。同时也可以从服务端查询当前注册的服务信息并把他们缓存到本地并周期性的刷新服务状态。

本文以Spring Boot 2.1.0版本为例,兼容的Spring Cloud为Greenwich版本。具体兼容关系如下:

Spring Cloud Spring Boot
Greenwich 兼容Spring Boot 2.1.x
Finchley 兼容Spring Boot 2.0.x,不兼容Spring Boot 1.5.x
Dalston和Edgware 兼容Spring Boot 1.5.x,不兼容Spring Boot 2.0.x
Camden 兼容Spring Boot 1.4.x,也兼容Spring Boot 1.5.x
Brixton 兼容Spring Boot 1.3.x,也兼容Spring Boot 1.4.x
Angel 兼容Spring Boot 1.2.x

1.2 使用Eureka进行服务治理

  1. 搭建服务注册中心

在Spring Boot工程中添加如下依赖:

<dependencies>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
    </dependency>
</dependencies>
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>Greenwich.M2</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

在Spring Boot工程的main入口,添加@EnableEurekaServer注解,开启服务注册中心:

@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
@RestController
@EnableEurekaServer
public class DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

在默认情况下,服务注册中心也会把自己当做是一个服务,将自己注册进服务注册中心,所以我们可以通过配置来禁用他的客户端注册行为,在application.yml中添加如下配置:

server:
  port: 8080
eureka:
  client:
    registerWithEureka: false
    fetchRegistry: false
    serviceUrl:
      defaultZone: http://localhost:8080/eureka

启动应用,并访问http://localhost:8080/即可看到Eureka信息面板。在"Instances currently registered with Eureka"信息中,没有一个实例,说明目前还没有服务注册。

  1. 注册服务

在另一个Spring Boot客户端工程中的pom文件中添加Eureka客户端相关的依赖:

<dependencies>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>
</dependencies>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>${spring-cloud.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

在主类上添加@EnableDiscoveryClient注解以实现Eureka中的DiscoveryClient实现

@EnableDiscoveryClient
@SpringBootApplication
@RestController
public class SpringCloudEurekaProviderApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringCloudEurekaProviderApplication.class, args);
    }

    @GetMapping("/hello")
    public String hello(){
        return "hello";
    }

}

最后在配置文件application.properties中配置与服务相关的一些基本信息,如服务名、注册中心地址(即上一节中设置的注册中心地址http://localhost:8080/eureka)

spring.application.name=service-provider
server.port=8081
eureka.client.service-url.defaultZone=http://localhost:8080/eureka/
eureka.instance.lease-renewal-interval-in-seconds=5
eureka.instance.leaseExpirationDurationInSeconds=10
  1. 测试

    1.启动注册中心服务
    2.启动客户端工程,可以看到如下信息,说明此服务已经注册在了注册中心:

    2018-12-07 16:45:14.620  INFO 14984 --- [           main] com.netflix.discovery.DiscoveryClient    : Discovery Client initialized at timestamp 1544172314617 with initial instances count: 0
    2018-12-07 16:45:16.668  INFO 14984 --- [nfoReplicator-0] com.netflix.discovery.DiscoveryClient    : DiscoveryClient_SERVICE-PROVIDER/windows10.microdone.cn:service-provider:8081: registering service...
    2018-12-07 16:45:16.979  INFO 14984 --- [nfoReplicator-0] com.netflix.discovery.DiscoveryClient    : DiscoveryClient_SERVICE-PROVIDER/windows10.microdone.cn:service-provider:8081 - registration status: 204
    
    

2. 服务提供与调用

本案例中有3个角色:服务注册中心、服务提供者、服务消费者,其中服务注册中心就是上一节的eureka单机版启动既可,流程是首先启动注册中心,服务提供者生产者服务并注册到服务中心中,消费者从服务中心中获取服务并执行。

2.1 服务提供

我们假定服务提供者有一个hello方法,可以提供输出“hello"的服务。

  1. pom包配置

    创建一个springboot项目,pom.xml中添加如下配置:

     <dependencies>
         <dependency>
             <groupId>org.springframework.cloud</groupId>
             <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
         </dependency>
     </dependencies>
     <dependencyManagement>
         <dependencies>
             <dependency>
                 <groupId>org.springframework.cloud</groupId>
                 <artifactId>spring-cloud-dependencies</artifactId>
                 <version>Greenwich.M1</version>
                 <type>pom</type>
                 <scope>import</scope>
             </dependency>
         </dependencies>
     </dependencyManagement>
    
  2. 配置文件

    application.properties配置如下:

     spring.application.name=service-provider
     server.port=8081
     eureka.client.service-url.defaultZone=http://localhost:8080/eureka/
     eureka.instance.lease-renewal-interval-in-seconds=5
     eureka.instance.leaseExpirationDurationInSeconds=10
    

    其中server.port指生产者服务的端口,eureka.client.service-url.defaultZone配置为上一节中服务注册中心配置的同名参数即可。

  3. 启动类和controller方法
    启动类上添加@EnableDiscoveryClient注解

@EnableDiscoveryClient
@SpringBootApplication
@RestController
public class SpringCloudEurekaProviderApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringCloudEurekaProviderApplication.class, args);
    }

    @GetMapping("/hello")
    public String hello(){
        return "hello";
    }

}

添加@EnableDiscoveryClient注解后,项目就具有了服务注册的功能。启动工程后,就可以在注册中心的页面看到SPRING-CLOUD-PRODUCER服务。

到此服务提供者配置就完成了。

2.2 服务调用

  1. pom包配置

    和服务提供者一致

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
    </dependencies>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Greenwich.M1</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    
  2. 配置文件
    application.properties配置如下:

    spring.application.name=service-consumer
     server.port=8082
    eureka.client.service-url.defaultZone=http://localhost:8080/eureka/
    eureka.client.register-with-eureka=false
    eureka.client.registry-fetch-interval-seconds=5
    
  3. 启动类和controller方法

    启动类添加@EnableDiscoveryClient注解。

@EnableDiscoveryClient
@SpringBootApplication
@RestController
public class SpringCloudEurekaConsumerApplication {
    private static final Logger log = LoggerFactory.getLogger(SpringCloudEurekaConsumerApplication.class);
    @Autowired
    RestTemplate restTemplate;

    @Bean
    @LoadBalanced
    RestTemplate restTemplate(){
        return new RestTemplate();
    }

    public static void main(String[] args) {
        SpringApplication.run(SpringCloudEurekaConsumerApplication.class, args);
    }

    @GetMapping("sayHi")
    public String sayHi(){
        final String ret = restTemplate.getForEntity("http://service-provider/hello", String.class).getBody();
        log.info("服务提供方返回结果:"+ ret);
        return ret;
    }

}

到此,最简单的一个服务注册与调用的例子就完成了。

2.3 测试

依次启动服务注册中心、服务提供者、服务消费者三个项目

先输入:http://localhost:8081/hello 检查生产者服务是否正常

返回:hello

说明生产者正常启动,提供的服务也正常。

浏览器中输入:http://localhost:8082/sayHi

返回:hello

说明消费者已经成功的调用了远程生产者的服务hello,并且将结果返回到了浏览器。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,372评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,368评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,415评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,157评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,171评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,125评论 1 297
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,028评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,887评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,310评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,533评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,690评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,411评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,004评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,659评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,812评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,693评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,577评论 2 353

推荐阅读更多精彩内容