SpringCloud —— Eureka详细使用教程,以及实战案例演示
一、引言Eureka 又称 服务注册中心,全部服务都需要进行注册才能使用,也是微服务架构中必不可少的一个组件。本章小编给大家讲解Eureka的使用方式,以及实战演示案例。版本:Spring Boot (2.1.3.RELEASE)、Spring Cloud (Greenwich.SR1),版本对应很重要,很多小伙伴因为版本不对而踩坑的案例很多啦,小编也是一路踩过来的。实战案例主要...
一、引言
Eureka 又称 服务注册中心,全部服务都需要进行注册才能使用,也是微服务架构中必不可少的一个组件。
本章小编给大家讲解Eureka的使用方式,以及实战演示案例。
版本:Spring Boot (2.1.3.RELEASE)、Spring Cloud (Greenwich.SR1),版本对应很重要,很多小伙伴因为版本不对而踩坑的案例很多啦,小编也是一路踩过来的。
实战案例主要内容:
服务:1、注册中心服务端 2、商品服务 3、订单服务
需求:订单服务需要查询商品信息完成下单服务, 服务商品提供商品查询的接口并且注册到服务中心,订单服务通过服务中心调用商品服务,从而拿到商品信息。
二、Eureka 服务端
步骤一:使用IDEA快速创建Spring Boot项目,并且选择Eureka服务端(记得把Web的引用也勾选上,不然会出现项目启动不了的情况)
步骤二:在Spring Boot启动类上加Eureka服务端注解
@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class, args);
}
}
步骤三:直接启动见证奇迹吧,默认端口应该是8080,http://localhost:8080,看到如下页面则表示服务端成功。
步骤四:如果按照以上步骤启动成功,控制台应该会抛出一下一段异常信息。这个异常是表示Eureka启动时会注册自己本身服务,而本身服务却还没启动成功,则抛出异常。
com.sun.jersey.api.client.ClientHandlerException: java.net.ConnectException: Connection refused (Connection refused)
解决办法:修改Eureka默认配置,小编默认习惯使用yml格式的配置文件,修改配置如下:
################ 项目基本配置 ################
spring:
application:
# 对应注册Eureka中的服务名
name: eureka
################ Eureka配置 ################
eureka:
client:
# 防止Eureka启动时注册本身服务
register-with-eureka: false
fetch-registry: false
三、Eureka 客户端
针对实战案例来说,需要创建一个商品项目、订单项目并且都需要注册到Eureka服务中心,以商品服务为例:
步骤一:还是采用IDEA快速创建Spring Boot项目,并且选择Eureka客户端依赖(记得吧Web也勾选上,不然会出现项目启动不了)
步骤二:配置Eureka服务端地址,还是yml格式的哟。
################ 项目基本配置 ################
server:
port: 8010
servlet:
# 项目访问路径前缀
context-path: /product
spring:
application:
# 注册到Eureka的服务名
name: product
################ Eureka配置 ################
eureka:
client:
service-url:
defaultZone: http://localhost:8080/eureka
步骤三:SpringBoot启动类上加上Eureka客户端注解,直接启动吧
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
@SpringBootApplication
@EnableEurekaClient
public class ProductApplication {
public static void main(String[] args) {
SpringApplication.run(ProductApplication.class, args);
}
}
步骤四:然后访问eureka后台管理页面,会发现有一个PRODUCT服务注册进来了,则表示没问题。
步骤五:我们会发现商品服务注册上来之后,页面会提示如下一句话,这个表示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:
client:
# 防止Eureka启动时注册本身服务
register-with-eureka: false
fetch-registry: false
server:
# 在开发环境时关闭服务心跳检测提示,在生产环境需要改为True
enable-self-preservation: false
四、Eureka 高可用
既然我们Eureka控制全场服务,那么单个服务注册中心肯定不够用,万一出现单点故障那就凉凉了。
所以再来说说Eureka怎么实现高可用,看Eureka服务端配置
################ Eureka配置 ################
eureka:
client:
# 防止Eureka启动时注册本身服务
register-with-eureka: false
fetch-registry: false
service-url:
# 另外一个Eureka服务地址,这里小编自定义了启动端口分别是:8761、8762
defaultZone: http://localhost:8761/eureka
server:
# 在开发环境时关闭服务心跳检测提示,在生产环境需要改为True
enable-self-preservation: false
启动两个eureka的项目,并且相互注册即可。
是不是炒鸡简单,只需要服务端往另外一个服务端注册即可,怎么看效果?
启动两个Eureka服务端,并且相互注册,然后我们使用商品服务往其中一个Eureka服务注册,如果看到两个Eureka服务端后台页面都有PRODUCT服务注册进来了,则表示成功。
有一个问题,现在我们商品服务只是往其中一个Eureka服务进行注册了,如果高可用其中一台Eureka挂掉了,那么商品服务再次注册的时候就会有问题,所以我们商品服务、订单服务注册Eureka的配置就需要改动,如下
################ Eureka配置 ################
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka,http://localhost:8762/eureka
五、Eureka 服务与服务之间调用方式
好了,以上全部内容都只是铺垫,以上只是演示了商品服务,那么订单服务也是同样的道理,都往Eureka上注册即可,小编就不说啦。
实战来啦,现在订单服务下单,订单服务需要通过前端传来的商品ID,调用商品的服务从而获取商品的金额、库存等。
商品服务:需要提供一个接口通过商品id查询商品具体信息,具体代码就不说了,重点在于订单服务怎么调用。
订单服务:已知商品ID,需要获取商品信息。
使用RestTemplate调用商品服务:
方式一:第一种方式很简单,直接调用RestTemplate方法即可。
/**
* 第一种方式直接指定路径,传参调用
* @param productId
* @return
*/
@GetMapping("/getOneProductById")
public Object getOneProductById(@RequestParam("productId") Integer productId){
MultiValueMap<String,Object> params = new LinkedMultiValueMap<>();
params.add("productId",productId);
RestTemplate template = new RestTemplate();
return template.postForObject("http://localhost:8010/product/getProductById", params, String.class);
}
方式二:通过LoadBalancerClient对象,需要你需要调用的服务,从而获得该服务的IP、端口信息等
@Autowired
private LoadBalancerClient loadBalancerClient;
/**
* 通过loadBalancerClient获取到注册服务对应到地址以及对应到端口号
* @param productId
* @return
*/
@GetMapping("/getTwoProductById")
public Object getTwoProductById(@RequestParam("productId") Integer productId){
// 这里的PRODUCT对应注册Eureka的服务名
ServiceInstance instance = loadBalancerClient.choose("PRODUCT");
String url = String.format("http://%s:%s/product/getProductById",instance.getHost(),instance.getPort());
MultiValueMap<String,Object> params = new LinkedMultiValueMap<>();
params.add("productId",productId);
RestTemplate template = new RestTemplate();
return template.postForObject(url, params, String.class);
}
方式三:需要配置一个Bean,主要是标注了LoadBalanced该注解。需要使用通过注解直接注入RestTemplate该对象,即可使用,代码如下:
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
/**
* @Auther: IT贱男
* @Date: 2019/3/26 10:39
* @Description:
*/
@Component
public class RestTemplateConfig {
@Bean
@LoadBalanced
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
@Autowired
private RestTemplate restTemplate;
/**
* 通过配置RestTemplate对象,通过服务名调用
* @param productId
* @return
*/
@GetMapping("/getThreeProductById")
public Object getThreeProductById(@RequestParam("productId") Integer productId){
MultiValueMap<String,Object> params = new LinkedMultiValueMap<>();
params.add("productId",productId);
// PRODUCT 对应注册Eureka中的服务名字
return restTemplate.postForObject("http://PRODUCT/product/getProductById", params, String.class);
}
使用Feign调用方式
首先我们需要引入依赖的Jar
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
配置每个服务的接口类,参数和路径都和商品服务一一对应。小编个人感觉这种方式稍微比较规范一点,实际项目中也使用的偏多。
/**
* @Auther: IT贱男
* @Date: 2019/3/26 10:48
* @Description: 定义商品服务接口信息
*/
@FeignClient(value = "PRODUCT")
public interface ProductFeignClient {
@PostMapping("/product/getProductById")
String getProductById(@RequestParam("productId") Integer productId);
}
使用方式注解注入服务接口定义类即可。
/**
* @Auther: IT贱男
* @Date: 2019/3/26 10:50
* @Description: 通过Feign实现调用商品服务
*/
@RestController
public class OrderFeignController {
@Autowired
private ProductFeignClient productFeignClient;
@GetMapping("/feign/getProductById")
public String getProductById(@RequestParam("productId") Integer productId){
return productFeignClient.getProductById(productId);
}
}
最最最最后千万要记住,SpringBoot启动类上需要加上Feign的注解。
@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
public class OrderApplication {
public static void main(String[] args) {
SpringApplication.run(OrderApplication.class, args);
}
}
最后效果都是能通过订单服务获取到商品信息的,才算没问题。
六、总结
Eureka是学习使用SpringCloud微服务的第一步,掌握服务的注册与发现是很基本的操作。
本实战案例以上传CSDN下载资源中,点击下载
后续组件都会通过本案例继续进行演示,如果本文又帮助到你,点个赞呗~~~
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)