第四章:spring cloud微服务开发(服务提供者和服务消费者)
1、服务提供者和服务消费者POM依赖
<!-- spring cloud Eureka Client 启动器 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency>
2、服务提供者代码如下所示:
a、启动类配置
@EnableEurekaClient @SpringBootApplication public class EurekaServerApplication { public static void main(String[] args) { SpringApplication.run(EurekaServerApplication.class, args); } }
b、Controller类
package com.yygx.eureka.controller; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; @Controller public class TestApplicationServiceController { @RequestMapping(value="/test") @ResponseBody public List<Map<String, Object>> test(){ List<Map<String, Object>> result = new ArrayList<>(); for(int i = 0; i < 3; i++){ Map<String, Object> data = new HashMap<>(); data.put("id", i+1); data.put("name", "test name " + i); data.put("age", 20+i); result.add(data); } return result; } @RequestMapping(value="/testMerge") @ResponseBody public List<Map<String, Object>> test(Long[] ids){ System.out.println(Thread.currentThread().getName() + " --------- " + Arrays.toString(ids)); List<Map<String, Object>> result = new ArrayList<>(); for(Long id : ids){ Map<String, Object> data = new HashMap<>(); data.put("id", id); data.put("name", "test name " + id); data.put("age", 20+id); result.add(data); } return result; } @RequestMapping("/toShutdown") public String toShutdown(){ return "shutdown"; } }
c、全局配置
spring.application.name=spring-cloud-eureka-appservice server.port=8080 eureka.client.serviceUrl.defaultZone=http://root:root@node01:8761/eureka/,http://root:root@node02:8761/eureka/
建议:如果有多个服务功能需要注册,那么在设置Eureka Server信息的时候,推荐异序排列。如:现在有3个工程A、B、C需要注册服务到Eureka Server集群中,集群节点有三个,分别是e1、e2、e3,那么在工程中推荐配置为,A工程配置-e1,e2,e3,B工程配置e2,e3,e1,C工程配置e3,e1,e2。这样可以更好的利用Eureka Server集群的特性。
3、服务消费者代码如下所示:
a、启动类配置同上
b、消费者代码
package com.yygx.eureka.controller; import java.util.List; import java.util.Map; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cloud.client.ServiceInstance; import org.springframework.cloud.client.loadbalancer.LoadBalancerClient; import org.springframework.core.ParameterizedTypeReference; import org.springframework.http.HttpMethod; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.client.RestTemplate; /** * 因为是测试案例,所以所有的代码都定义在了Controller中。 * 商业开发中,业务逻辑和远程调用Provider的代码逻辑应该封装在Service代码中。 * 现在的代码编写方式,只是为了看起来方便。 * * 在这里开发Eureka Client中的Application Client角色。就是consumer服务的消费者。 * 服务消费者需要在注册中心中发现服务列表的。且同时将自己注册到注册中心的服务列表中。 * * consumer在消费provider的时候,是通过LoadBalancer来实现的。 * LoadBalancer后续课程中详细讲解。 * LoadBalancer简介 : 是Eureka client内置的一个负载均衡器。复杂在发现的服务列表中选择服务应用,获取服务的IP和端口。 * 实现服务的远程调用。 * * application client代码开发相比较dubbo的consumer开发麻烦很多。 * */ @RestController public class TestApplicationServiceController { /** * ribbon负载均衡器,其中记录了从Eureka Server中获取的所有服务信息。 * 这些服务的信息是IP和端口等。应用名称,域名,主机名等信息。 */ @Autowired private LoadBalancerClient loadBalancerClient; /** * 通过HTTP协议,发起远程服务调用,实现一个远程的服务消费。 * @return */ @GetMapping("/test") public List<Map<String, Object>> test() { // 通过spring应用命名,获取服务实例ServiceInstance对象 // ServiceInstance 封装了服务的基本信息,如 IP,端口 /* * 在Eureka中,对所有注册到Eureka Server中的服务都称为一个service instance服务实例。 * 一个服务实例,就是一个有效的,可用的,provider单体实例或集群实例。 * 每个service instance都和spring application name对应。 * 可以通过spring application name查询service instance */ ServiceInstance si = this.loadBalancerClient.choose("spring-cloud-eureka-appservice"); // 拼接访问服务的URL StringBuilder sb = new StringBuilder(); // http://localhost:8081/test sb.append("http://").append(si.getHost()) .append(":").append(si.getPort()).append("/test"); System.out.println("本次访问的service是: " + sb.toString()); // SpringMVC RestTemplate,用于快速发起REST请求的模板对象。 /* * RestTemplate是SpringMVC提供的一个用于发起REST请求的模板对象。 * 基于HTTP协议发起请求的。 * 发起请求的方式是exchange。需要的参数是: URL, 请求方式, 请求头, 响应类型,【URL rest参数】。 */ RestTemplate rt = new RestTemplate(); /* * 创建一个响应类型模板。 * 就是REST请求的响应体中的数据类型。 * ParameterizedTypeReference - 代表REST请求的响应体中的数据类型。 */ ParameterizedTypeReference<List<Map<String, Object>>> type = new ParameterizedTypeReference<List<Map<String, Object>>>(){} ; /* * ResponseEntity:封装了返回值信息,相当于是HTTP Response中的响应体。 * 发起REST请求。 */ ResponseEntity<List<Map<String, Object>>> response = rt.exchange(sb.toString(), HttpMethod.GET, null, type); /* * ResponseEntity.getBody() - 就是获取响应体中的java对象或返回数据结果。 */ List<Map<String, Object>> result = response.getBody(); return result; } }
c、全局配置
spring.application.name=spring-cloud-eureka-appclient server.port=8081 eureka.client.serviceUrl.defaultZone=http://root:root@node01:8761/eureka/,http://root:root@node02:8761/eureka/
4、测试