赞
踩
Eureka 又称 服务注册中心,全部服务都需要进行注册才能使用,也是微服务架构中必不可少的一个组件。
本章小编给大家讲解Eureka的使用方式,以及实战演示案例。
版本:Spring Boot (2.1.3.RELEASE)、Spring Cloud (Greenwich.SR1),版本对应很重要,很多小伙伴因为版本不对而踩坑的案例很多啦,小编也是一路踩过来的。
实战案例主要内容:
服务:1、注册中心服务端 2、商品服务 3、订单服务
需求:订单服务需要查询商品信息完成下单服务, 服务商品提供商品查询的接口并且注册到服务中心,订单服务通过服务中心调用商品服务,从而拿到商品信息。
步骤一:使用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服务中心,以商品服务为例:
步骤一:还是采用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:
- 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上注册即可,小编就不说啦。
实战来啦,现在订单服务下单,订单服务需要通过前端传来的商品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下载资源中,点击下载
后续组件都会通过本案例继续进行演示,如果本文又帮助到你,点个赞呗~~~
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。