服务发现组件 Eureka 实现服务间的调用组件Feign

2022-05-13 10:30:28 浏览数 (1)

1 Eureka简介和组成

EurekaNetflix公司开发的服务发现框架,SpringCloud将它集成在自己的子项目 spring-cloud-netflix中,实现SpringCloud的服务发现功能。Eureka包含两个组件: Eureka Server和Eureka Client。

  • Eureka Server提供服务注册服务,各个节点启动后,会在Eureka Server中进行注册,这样EurekaServer中的服务注册表中将会存储所有可用服务节点的信息,服务节点的信息可以在界面中直观的看到。
  • Eureka Client是一个java客户端,用于简化与Eureka Server的交互,客户端同时也 就别一个内置的、使用轮询(round-robin)负载算法的负载均衡器。在应用启动后,将会 向Eureka Server发送心跳,默认周期为30秒,如果Eureka Server在多个心跳周期内没有 接收到某个节点的心跳,Eureka Server将会从服务注册表中把这个服务节点移除(默认90 秒)。
  • Eureka Server之间通过复制的方式完成数据的同步,Eureka还提供了客户端缓存机制,即使所有的Eureka Server都挂掉,客户端依然可以利用缓存中的信息消费其他服务的API。综上,Eureka通过心跳检查、客户端缓存等机制,确保了系统的高可用性、灵活 性和可伸缩性。

2. Eureka实战

(1)引入依赖 父工程pom.xml定义SpringCloud版本

代码语言:javascript复制
<dependencyManagement>
        <dependencies>
            <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-dependencies -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Finchley.M9</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

子服务模块pom.xml引入eureka-server

代码语言:javascript复制
<dependencies> 
<dependency>
  <groupId>org.springframework.cloud</groupId> 
  <artifactId>spring‐cloud‐starter‐netflix‐eureka‐ server</artifactId> 
</dependency>//这里无需指定版本号,因为我们在父pom里已经进行了版本控制
 </dependencies>
代码语言:javascript复制
服务端yml配置
server:
  port: 6868
eureka:
  client:
    register-with-eureka: false  #是否注册到eureka服务器上选择false,因为这是一个服务器模块
    fetch-registry: false #是否拿到注册
    service-url:
      defaultZone: http://127.0.0.1:${server.port}/eureka/


客户端yml配置
eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:6868/eureka/
  instance:
    prefer-ip-address: true #部署导线上时,可以使模块之间跨域访问

Feign实现服务间的调用

Feign是简化Java HTTP客户端开发的工具 (java-to-httpclient-binder),它的灵感 来自于Retrofit、JAXRS-2.0和WebSocket。 Feign的初衷是降低统一绑定Denominator到 HTTP API的复杂度,不区分是否为restful。Spring Cloud集成了Ribbon和Eureka,可在使用Feign时提供负载均衡的http客户端。

Feign快速体验 举例qa项目调用base项目

(1)qa模块(客户端模块)添加Feign调用依赖

代码语言:javascript复制
<dependency> 
<groupId>org.springframework.cloud</groupId> 
<artifactId>spring-cloud-starter-openfeign</artifactId>
 </dependency>

qa的启动类上增加两个注解

代码语言:javascript复制
@SpringBootApplication//原有-springboot启动类
@EnableEurekaClient//原有-标明这里是一个服务组件并注册到Eureka
@EnableDiscoveryClient//增加-使的qa服务可以去发现其他服务
@EnableFeignClients//增加- 使的qa服务可以去调用其他服务

编写需要调用的模块的接口

代码语言:javascript复制
package com.tensquare.qa.client;

import entity.Result;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@FeignClient("tensquare-base")
//@FeignClient("tensquare-base")指定调用的服务是哪个
/*
这里的tensquare-base其实是我们在写base服务module时候在yml中指定的名字
spring: 
  application:  
    name: tensquare-base
*/
public interface BaseClient {//调用base的接口
    @RequestMapping(value = "label/{labelId}",method = RequestMethod.GET)
//注意这里RequestMapping里的value要写全label也要写,因为要指定到一个全路径,类似于直接在浏览器输入时候的访问地址
    public Result findById(@PathVariable("labelId") String labelId);//Base中被调用的方法
    //这里必须@PathVariable("labelId") 指定labelId,因为RequestMappering里的labelId是传到PathVariable中的
    //这样在tensquare_base模块中才会在RequestMapper中
}

qa模块中Controller的写法(部分)

代码语言:javascript复制
@RequestMapping("/problem")
public class ProblemController {
    @Autowired
    private BaseClient baseClient;
    //注入我们在qa模块写的base服务模块调用接口
    @RequestMapping(value = "label/{labelId}",method = RequestMethod.GET)
    //写的和base接口中一样就行
    public Result findByLabelId(@PathVariable String labelId){
        Result result = baseClient.findById(labelId);
        return result;
    }

这样我们一个Fegin快速调用入门就结束了 我们可以用postman时候可以模拟get请求 访问: http://localhost:9003/problem/label/1 请求就会先从9003模块的problemController层通过RequestMapping找到findByLabelId会调用baseClient.findById(labelId)方法,这个时候呢,我们在BaseClient上配的@FeignClient("tensquare-base")就起了作用,他会转化请求到base微服务模块 并带着@RequestMapping中的地址和qa传过来的参数值

代码语言:javascript复制
 @RequestMapping(value = "label/1",method = RequestMethod.GET)
    //写的和base接口中一样就行
    public Result findByLabelId(1);

SpringCloud的负载均衡

当我们采用不同端口开启多个base服务一个qa服务时候,我们利用qa去调用base时候发现请求到base集群时候实际上是每个base轮流处理请求即轮询 其实SpringCloud集成了Netfix Ribbon实现了一套客户端 负载均衡的工具。

0 人点赞