第四章: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、测试

 

posted on 2018-12-06 21:29  唯伊  阅读(270)  评论(0编辑  收藏  举报

导航