文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

如何用Eureka + Feign搭建分布式微服务

2024-04-02 19:55

关注

Eureka

Eureka主要解决了消费者对服务的记忆问题。如果没有Eureka,那么消费者必须记忆每个服务的地址,且一旦服务提供者宕机或地址发生变更,很可能不会收到通知,导致地址失效。加入Eureka后,只需记住Eureka注册中心的地址就能够找到其它所有服务。

此外,Eureka能够接受多个服务的注册,还能够通过其它组件的加持直接替代消费者进行负载均衡,使消费者无需手动选择服务。

Feign

Feign是一个模板化的HTTP客户端。通过Feign,可以做到像调用一个本地方法一样请求远程服务,无需编写繁杂的代码来创建HTTP请求。

创建父项目

项目主要分为三个微服务:服务提供者、服务消费者、Eureka注册中心。为了方便演示,三个项目都在同一个主机上运行,且都放在一个父项目里。

首先在IDEA中创建一个空项目,然后分别在项目中新建对应的三个Spring模块:

注册中心

服务提供者通过向注册中心注册,提供它们的地址供调用;服务消费者向注册中心请求来获取可用的服务。

主要依赖


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

配置文件


# 端口
server.port=1000
# 指定应用名称
spring.application.name=server
# 是否拉取其它服务器的注册信息
eureka.client.fetch-registry=false
# 是否向其它服务器注册
eureka.client.register-with-eureka=false
# 指定服务url
eureka.client.service-url.defaultZone=http://localhost:1000/eureka

默认情况下,Eureka服务器假定自己是集群的一部分,会定期向其它Eureka服务器注册自己,并获取其它服务器的注册信息。由于本项目仅部署一个Eureka服务器提供注册服务,所以不需要这两个动作,通过配置文件的eureka.client.fetch-registry和eureka.client.register-with-eureka两个属性禁用。

eureka.client.service-url包含了每个zone的名称和地址。defaultZone是一个特殊的key,如果客户端没有指定所需的zone,就会使用这个默认的zone。一般情况下defaultZone的地址就是Eureka服务器本身。

主类


@SpringBootApplication
@EnableEurekaServer
public class MyEurekaServerApplication {

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

要启动Eureka注册服务,在原生的Spring Boot启动类上注解@EnableEurekaServer即可。

项目启动后,访问localhost:1000就能看到Eureka提供的界面了。如果在界面上看到警告

EMERGENCY! EUREKA MAY BE INCORRECTLY CLAIMING INSTANCES ARE UP WHEN THEY'RE NOT. RENEWALS ARE LESSER THAN THRESHOLD AND HENCE THE INSTANCES ARE NOT BEING EXPIRED JUST TO BE SAFE.

是正常现象。Eureka服务器默认开启了自我保护模式。由于没有收到集群中大部分服务器的心跳(本项目中就一个Eureka服务器,所以该服务器不会收到任何心跳,自我保护模式也没有多少影响),Eureka假定出现了网络问题,开启自我保护模式。在自我保护模式下,已经注册的服务不会因为没有收到心跳而被注销。

如果要关闭自我保护,可以在配置中设置如下属性。


eureka.server.enable-self-preservation=false

服务提供者

服务提供者将自己注册到注册中心。

主要依赖


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

spring-cloud-starter-netflix-eureka-client依赖包含了Eureka客户端(即服务提供者)的实现;spring-boot-starter-web用于将服务暴露为HTTP端点。

配置文件


# 应用端口
server.port=2000
# 应用名称
spring.application.name=service
# 注册中心地址
eureka.client.service-url.defaultZone=http://localhost:1000/eureka

eureka.client.service-url.defaultZone属性告诉Eureka客户端从哪里找到注册中心。

主类及Controller


@SpringBootApplication
public class MyEurekaServiceApplication {

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

}

@RestController
@RequestMapping("/test")
@Slf4j
class MyController {
    @Value("${server.port}")
    private int serverPort;

    @GetMapping
    public String getHandler() {
        log.info("##############received call, port: " + this.serverPort);
        return "test msg";
    }
}

为了展示方便,这些类都写在同一个文件中,下同。

这里的Controller提供了一个简单的服务:只要访问/test路径,就返回一个字符串test msg。如果有需要,可以同时启动多个服务实例,模拟服务器集群提供服务的情况。

@Slf4j是lombok提供的辅助注解,用于在类中方便地声明一个Logger实例log。

@Value是Spring提供的注解,用于获取配置文件中的信息。本例中就获取了之前配置的属性server.port=2000的值2000,注入到域serverPort中。

启动服务提供者后,会自动向配置文件中指定的Eureka服务器进行注册。此时访问之前的Eureka服务器界面,能够看到已经注册的服务信息。这里我分别修改端口号启动了3个实例。

此时访问服务提供者所在端口的/test路径就能够收到服务提供的字符串。

客户端

Feign是一个模板化的HTTP客户端。通过Feign,可以做到像调用一个本地方法一样请求远程服务,无需编写繁杂的代码来创建HTTP请求。

客户端通过Feign的加持,可以方便地发出请求,也可以加入Hystrix的负载均衡、熔断降级等功能。

主要依赖


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

配置文件


# 应用端口
server.port=3000
# 应用名称
spring.application.name=feignClient
# 注册中心地址
eureka.client.service-url.defaultZone=http://localhost:1000/eureka

同上,eureka.client.service-url.defaultZone属性指定了客户端应该到哪个地址寻找注册中心。

主类、Controller及Feign映射


@FeignClient(value = "service")
interface FeignController {
    @GetMapping("/test")
    public String getHandler();
}

@SpringBootApplication
@EnableFeignClients
@EnableDiscoveryClient
public class MyFeignClientApplication {

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

}

@RestController
@RequestMapping("/test")
class MyRestController {
    @Autowired
    FeignController feignController;

    @GetMapping
    public String getHandler() {
        return feignController.getHandler();
    }
}

类中的接口FeignController将发往该端口的HTTP请求映射为向服务的请求。本例中,@FeignClient(value = "service")指定了将调用映射为向service服务的请求。而用@GetMapping("/test")则代表每当调用该方法,就向/test路径请求。综上,每当调用该方法,该服务就会向名为service的服务的/test路径发送HTTP GET请求。这就是Feign的方便之处。

在启动类上需要注解@EnableFeignClients和@EnableDiscoveryClient,启动对Feign接口的扫描和对Eureka服务器的发现。

类中还写了一个MyRestController,用于将对该服务的请求映射到方法调用。调用链为:

这样一来,用户体验到的过程就是:通过Feign发送了一个请求,然后收到了远程服务器上的信息。

启动客户端,访问客户端所在端口的/test路径,正确收到了服务提供的字符串。

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯