微服务feign接口调用 eureka feign微服务间通信_spring

1.什么是eureka

eureka(服务发现框架)是Netflix开源的服务发现组件,本身是一个基于rest(一种软件架构风格)的服务。它包含server和client两部分。springcloud将它集成在子项目springcloudNetflix中。

功能:微服务的注册与发现

2.eureka原理

我们可以看下eureka的架构图

微服务feign接口调用 eureka feign微服务间通信_eureka_02

其中 application service可以理解为服务提供者,application client为服务消费者,make remote call为调用restful api 的行为,而us-east-1c,us-east-1d等都是zone,都属于us-east-1这个region

有图可知,eureka包括server和client两个组件,他们的作用分别是:

eureka server:提供服务发现的能力,各个微服务启动时,会向注册中心(eureka server)注册自己的信息(例如IP,端口,微服务名称等),注册中心会存储这些信息。

eureka client:这是Java客户端,用于简化与eureka server的交互,提供微服务(服务提供者)。

微服务启动后,会周期性的(默认30秒)向eureka server 发送心跳使得自己keep alive。如果在一定时间内(默认90秒)注册中心没有接收到某个微服务的心跳,注册中心会注销该实例。这使得系统具有灵活性。

eureka client 会缓存服务注册表中的信息,这使得微服务无须每次请求都得查询eureka server,提高了效率,此外,即使eureka server 所有的节点都宕掉,client 依然可以利用缓存中的信息找到服务提供者并完成调用,保证了系统的高可用性。

3.简单的代码实现

3.1首先是编写一个eureka server(注册中心)

3.1.1pom文件引入相关的依赖(eureka依赖)

<!--        eureka依赖导入服务端-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>

这里最好把spring cloud 父依赖也引入进来,避免手动配置版本,出现各种奇怪的问题。

<dependencyManagement>
<!--        spring cloud 父依赖导入  版本控制 避免自己手动选择版本出错-->
        <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>

3.1.2编写启动类,重点是添加注解@EnableEurekaServer

//启动类入口需要增加注解@EnableEurekaServer
@SpringBootApplication
@EnableEurekaServer

public class EurekaApplication {

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

}

3.1.3在配置文件application.propercitis添加一下配置

其中两个置为false是关键,将自己声明为eureka server。配置完成后,启动即可。

#eureka服务的端口
server.port=8080
#服务名称
spring.application.name=eureka-zeron
#优先IP
eureka.instance.prefer-ip-address=true
#不要获取注册表中的信息(服务端)
eureka.client.fetch-registry=false
#防止将自己注册到注册中心去(服务端)
eureka.client.register-with-eureka=false
#eureka server地址
eureka.client.service-url.defaultZone=http://localhost:8080/eureka/

微服务feign接口调用 eureka feign微服务间通信_微服务feign接口调用_03

3.2 将微服务注册到eureka server上

3.2.1pom文件引入依赖

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

3.2.1编写一个微服务,提供接口供调用。(以订单服务为例)部分代码如下:

//通过ID可以查询对应商品的信息,或者selectAll返回所有商品的信息
@RestController
@RequestMapping("/myTest")
public class goodController {
    @Autowired
    private GoodService goodService;

    @RequestMapping(value = "/getGoodByID",method = RequestMethod.GET)
public String getGood(int goodID){
return goodService.getGoodInfo(goodID).toString();
}

@RequestMapping("/selectAll")
    @ResponseBody
public List<Good> ListGood(){
    return goodService.selectAll();
}
}

3.2.2在配置文件application.propercitis添加一下配置

#eureka-client
#自己的运行端口
server.port=8099
#服务名称
spring.application.name=eureka-miss
#优先IP
eureka.instance.prefer-ip-address=true
#获取注册表中的信息
eureka.client.fetch-registry=true
#注册到eureka-server
eureka.client.register-with-eureka=true
#注册地址(与前面的eureka-server地址一致)
eureka.client.service-url.defaultZone=http://localhost:8080/eureka/

 这里与eureka-server不同的在于,当然也可以不写,默认为true。

eureka.client.register-with-eureka=false

eureka.client.fetch-registry=false

3.2.3编写启动类,加入注解@EnableEurekaClient

@SpringBootApplication
@EnableEurekaClient
public class EurekaClientApplication {

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

}

值得一提的是

微服务feign接口调用 eureka feign微服务间通信_Cloud_04

 至此,完成了一个eureka-server(注册中心)的搭建,并将一个微服务注册在上面。

4.eureka高可用

刚前面提到,eureka-client利用缓存机制,即使在eureka-server宕机的情况下,仍然可以通过缓存中的信息找到微服务并完成调用。现在假定出现这样的情况,eureka-server宕机的同时,某些微服务也出现了不可用的情况,如果eureka-client中的缓存不被更新,就会影响到微服务之间的调用,甚至影响到整个系统的高可用性,因此,在实际生产环境中,我们需要部署一个高可用的eureka-server集群。

我们前面在编写单节点eureka-server时,在配置文件中添加了以下内容

eureka.client.register-with-eureka=false

eureka.client.fetch-registry=false

eureka server 可以通过运行多个实例并且相互注册的方式实现高可用部署,eureka server实例会彼此增量地同步信息,从而确保所有节点数据一致。实现方式非常简单,只需将上述两项置为ture(或者不写),然后注册到另外一个注册中心上去,这里的注册中心地址不再是它本身,而是另外一个注册中心的地址,它本身作为eureka client 注册到上面去。配置文件如下:

server.port=8081

#eureka
#服务名称
spring.application.name=eureka-miss

eureka.instance.prefer-ip-address=true

#另外一个注册中心的地址
eureka.client.service-url.defaultZone=http://localhost:8080/eureka/

这样就实现了将节点2注册到节点1的过程。接下来是将服务注册到eureka server 集群上。

实现也非常简单,如下所示,只需要配置多个eureka server地址即可,地址之间用,隔开。

eureka.client.service-url.defaultZone=http://localhost:8080/eureka/,http://localhost:8081/eureka/

5.feign实现微服务之间的调用

5.1feign简介

Feign是Netflix开发的声明式、模板化的HTTP客户端, Feign可以帮助我们更快捷、优雅地调用HTTP API。

在Spring Cloud中,使用Feign非常简单——创建一个接口,并在接口上添加一些注解,代码就完成了。Feign支持多种注解,例如Feign自带的注解或者JAX-RS注解等。

Spring Cloud对Feign进行了增强,使Feign支持了Spring MVC注解,并整合了Ribbon和Eureka,从而让Feign的使用更加方便。

Spring Cloud Feign是基于Netflix feign实现,整合了Spring Cloud Ribbon和Spring Cloud Hystrix,除了提供这两者的强大功能外,还提供了一种声明式的Web服务客户端定义的方式。

Spring Cloud Feign帮助我们定义和实现依赖服务接口的定义。在Spring Cloud feign的实现下,只需要创建一个接口并用注解方式配置它,即可完成服务提供方的接口绑定,简化了在使用Spring Cloud Ribbon时自行封装服务调用客户端的开发量。

Spring Cloud Feign具备可插拔的注解支持,支持Feign注解、JAX-RS注解和Spring MVC的注解。
5.2feign简单实践

这里编写两个服务(用户服务和订单服务)和一个服务注册中心,两个服务注册在注册中心上并且能够相互访问,订单服务提供一个接口,该接口作用是可以通过商品ID获取商品信息(单价,种类,库存等),用户服务使用openfeign通过注册中心实现对该接口的调用。接口具体实现逻辑不再展示,主要看如何使用feign实现微服务间调用。

首先是往调用者的pom文件里引入依赖,被调用者不需要引入。

<!--        引入openfeign依赖-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>

接着是创建一个feign接口,并且添加@FeignClient注解,如下所示

//必须加入component注解 否则在controller层无法注入,加入component 把对象创建交给spring完成
@Component
//加入这个注解 并且name值必须与被调用服务注册在注册中心上的名称一致
@FeignClient(name = "HONGSHEN-WEAVING")

public interface GoodService {
    //这个value值要与被调用的服务里面的路径一致
    @RequestMapping(value = "/myTest/getGoodByID",method = RequestMethod.GET)
    //记住加入@RequestParam("goodID")  否则会报错(500)
    String findByID(@RequestParam("goodID") int goodID);

    //返回所有的商品列表
    @RequestMapping("/myTest/selectAll")
    List selectAllGood();
}

在controller层添加代码,调用该feign接口

@Autowired
    private GoodService goodService;
    //

    @GetMapping("/findGoodByID")
    public String findGoodByID(int goodID){
        return goodService.findByID(goodID);
    }

往启动类添加注解@EnableFeignClients

//必须加入@EnableEurekaClient和@EnableFeignClients注解

@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
public class SpringdemoApplication {

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

}

至此配置完成,启动注册中心,启动微服务,在地址栏输入对应URL,即可实现微服务间调用。