Spring Cloud 入门系列三 -- Eureka 之服务提供与调用

我的上一篇博客已经介绍过了 Eureka 的服务注册中心功能如何使用,在本文,我将搭建一个小程序,来实现服务端注册服务而客户端调用服务的案例。

1 Eureka 基本架构的三种角色

  1. 服务注册中心:用于提供服务注册和发现
  2. 服务提供者:将自身服务注册到 Eureka 中,令服务消费者调用
  3. 服务消费者:从 Eureka 获得注册服务列表,以便消费服务

我上篇文章已介绍过服务注册中心的实现,本文章我将重点介绍服务提供者和服务消费者的实现。

2 服务提供者的构建

我们新建一个项目,并命名为 EurekaProducer 。

2.1 引入依赖

		<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</artifactId>
		</dependency>
		
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
		
		<dependency>
        	<groupId>org.springframework.boot</groupId>
        	<artifactId>spring-boot-starter-web</artifactId>
 		</dependency>
		
		<dependency>
            <groupId>javax.xml.bind</groupId>
            <artifactId>jaxb-api</artifactId>
        </dependency>
        <dependency>
            <groupId>com.sun.xml.bind</groupId>
            <artifactId>jaxb-impl</artifactId>
            <version>2.3.0</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.jaxb</groupId>
            <artifactId>jaxb-runtime</artifactId>
        </dependency>
        <dependency>
            <groupId>javax.activation</groupId>
            <artifactId>activation</artifactId>
            <version>1.1.1</version>
        </dependency>

2.2 application.properties

spring.application.name=producer
server.port=8080
# 设置与Eureka Server交互的地址,查询服务和注册服务都需要依赖这个地址
eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/

2.3 启动类

我们需要在启动类上添加 @EnableDiscoveryClient 注解,该注解用于启动服务的注册与发现。

package com.example.EurekaProducer;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

@SpringBootApplication
@EnableDiscoveryClient
public class EurekaProducerApplication {

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

}

2.4 控制器

package com.example.EurekaProducer.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class HelloWorldController {

	@RequestMapping("/helloWorld")
	@ResponseBody
	public String helloWorld(int id,String saying) {
		return "序号为" + id + "的用户发布了一条新消息:" + saying;
	}
}

2.5 测试

启动 Eureka,EurekaProducer 两个项目,然后打开 Eureka 界面

在这里插入图片描述
我们可以发现该服务已注册到 Eureka 。

然后我们在浏览器输入 http://localhost:8080/helloWorld?id=2&saying=%E7%89%9B%E9%80%BC,发现服务正常。
在这里插入图片描述

3 服务消费者的构建

我们新建一个项目,并命名为 EurekaConsumer 。

3.1 引入依赖

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

		<dependency>
        	<groupId>org.springframework.boot</groupId>
        	<artifactId>spring-boot-starter-web</artifactId>
 		</dependency>
		
		<dependency>
            <groupId>javax.xml.bind</groupId>
            <artifactId>jaxb-api</artifactId>
        </dependency>
        <dependency>
            <groupId>com.sun.xml.bind</groupId>
            <artifactId>jaxb-impl</artifactId>
            <version>2.3.0</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.jaxb</groupId>
            <artifactId>jaxb-runtime</artifactId>
        </dependency>
        <dependency>
            <groupId>javax.activation</groupId>
            <artifactId>activation</artifactId>
            <version>1.1.1</version>
        </dependency>

这里注意,除了 Eureka 的配置之外,我们还需要引入 Feign 的配置。Feign 是一个声明式 Web Service 客户端,用于远程调用。关于更多的 Feign 知识,我们会在下一篇博客介绍。

3.2 application.properties

spring.application.name=consumer
server.port=8082
# 设置与Eureka Server交互的地址,查询服务和注册服务都需要依赖这个地址
eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/

3.3 启动类

package com.example.EurekaConsumer;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;

@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class EurekaConsumerApplication {

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

}

我们需要在启动类上添加 @EnableDiscoveryClient,@EnableFeignClients 两个注解,其中 @EnableFeignClients 用于启用 feign 进行远程调用。

3.4 启动 feign 调用

package com.example.EurekaConsumer.Service;

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

@Component
@FeignClient(name= "producer")//name为远程服务名,即远程服务spring.application.name设置的名字
public interface HelloWorldService {

	//调用方法需要与远程服务中的方法名和参数一致
	@RequestMapping("/helloWorld")
    public String helloWorld(@RequestParam(value = "id")int id,@RequestParam(value = "saying")String saying);
}

注意点已经在注解中标出。

3.5 控制层调用远程服务

package com.example.EurekaConsumer.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.example.EurekaConsumer.Service.HelloWorldService;

@Controller
public class HelloWorldController {

	@Autowired
	HelloWorldService helloWorldService;
	
	@ResponseBody
	@RequestMapping("/helloWorld")
	public String use(int id,String saying) {
		return helloWorldService.helloWorld(id, saying);
	}
}

就像调用普通方法一样即可。至此,我们的服务注册与调用例子已经实现完毕。

3.6 测试

启动 Eureka,EurekaProducer,EurekaConsumer 三个项目,然后打开 Eureka 界面
在这里插入图片描述
两个服务均已注册到 Eureka。我们首先在浏览器输入 http://localhost:8080/helloWorld?id=3&saying=%E7%89%9B%E9%80%BC,发现 EurekaProducer 提供的服务正常。
在这里插入图片描述
然后我们输入 http://localhost:8082/helloWorld?id=4&saying=%E7%89%9B%E9%80%BC,发现 EurekaConsumer 已经成功通过 feign 调用了远程服务。至此,我们的测试结束。
在这里插入图片描述

4 对 Eureka 使用的总结

  1. Eureka 客户端会每隔30秒会发送一次心跳续约,通过续约来告知 Eureka Server 该客户端仍然存在,即服务续约。
  2. Eureka 客户端会从服务器获取注册表信息,并将其缓存在本地。客户端会使用该信息查找其他服务,从而进行远程调用。该注册列表信息每30秒钟更新一次。每次返回注册列表信息可能与 Eureka 客户端的缓存信息不同, Eureka客户端会进行自动处理。如果注册列表信息不能及时匹配,Eureka客户端则会重新获取整个注册表信息。
  3. Eureka 客户端在程序关闭时会向 Eureka 服务器发送取消请求。发送请求后,该客户端实例信息将从服务器的实例注册表中删除。该下线请求不会自动完成,它需要调用以下内容:
    DiscoveryManager.getInstance().shutdownComponent(),即服务下线。
  4. 默认情况下,如果 Eureka 客户端连续90秒没有向 Eureka 服务器发送服务续约,Eureka
    服务器会将该服务实例从服务注册列表删除,即服务剔除。

參考:springcloud(三):服务提供与调用

发布了113 篇原创文章 · 获赞 206 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/Geffin/article/details/102729954