您的位置:首页 > 编程语言 > Java开发

嗡汤圆的Spring Cloud自学(PART.2):eureka服务注册与代理端使用

2016-10-12 23:09 811 查看

前言

传统的微服务的调用一般是直接再客户端发送请求到微服务的地址和端口进行调用,或者当微服务有多个副本时,通过配置nginx反向代理进行负载均衡。

客户端直接调用:



或者nginx负载:



以上两种情况均需要手动维护微服务的应用地址和端口,不易于微服务集群维护,当微服务出错或者关闭时,可能引起服务异常。

因此,若可以让微服务在启动后自行在一个地方注册,并统一管理微服务地址则省去了手动维护服务地址的麻烦。同时统一管理平台也可以监视各个微服务的运行状态。



注册服务(eureka)

通过假设Spring-eureka-server可以方便的构建这种微服务平台。

eureka项目构建

通过start.spring.io或者maven构建即可。若使用start.spring.io,则勾选eureka-server 和 config-client 即可,POM文件省略。

在设置
application.properties
中设置端口
server.port=8761


在设置
bootstrap.properties
中设置应用名称为:eureka-server

在启动application.java入口中加入注解
@EnableEurekaServer


@EnableEurekaServer
@SpringBootApplication
public class EurekaServerApplication {

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


启动效果

启动后,访问该项目:
http://localhost:8761
即可看到eureka的服务页面,从页面中可以看见,服务列表中有一个eureka-server服务,即该项目自身。



服务注册

将上一篇博客中的reservation-service注册到eureka中,则仅需添加eureka依赖:

<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>


然后在启动代码中添加注解
@EnableDiscoveryClient
即可:

@EnableDiscoveryClient
@SpringBootApplication
public class ReservationServiceApplication {
public static void main(String[] args) {
SpringApplication.run(ReservationServiceApplication.class, args);
}
}


启动reservation-service项目,再刷新eureka页面,可以看见服务已注册:



代理端

代理端的作用在于代替原微服务接受请求,并将请求转发至可用的微服务中获取结果后,将结果处理并送回给客户端。

本例中的代理端将根据客户端的请求信息从eureka服务中查找可用的服务接口地址,并将请求传递下去。

代理端项目构建

在start.spring.io中勾选
eureka discovery
config-client
即可。若需要对请求进行加工处理和监视,也可勾上
zuul
(边缘代理或edge proxy)组件。POM文件省略。

在Application入口中加入注解
@EnableZuulProxy @EnableDiscoveryClient
即可。

@EnableZuulProxy
@EnableDiscoveryClient
@SpringBootApplication
public class ReservationClientApplication {
public static void main(String[] args) {
SpringApplication.run(ReservationClientApplication.class, args);
}
}


配置
application.properties
将端口设置为8800,配置eureka服务的地址(可选)。

server.port=8800
eureka.instance.client.serviceUrl.defaultZone: http://localhost:8761/eureka/[/code] 

代理使用

获取API服务信息

通过
DiscoveryClient.getInstances(String)
方法获得,其中参数为服务名(此例子中的reservation-service)。代码如下:

@Autowired
private DiscoveryClient discoveryClient;

@RequestMapping("/service-instances/{applicationName}")
public List<ServiceInstance> serviceInstancesByApplicationName(
@PathVariable String applicationName) {
return this.discoveryClient.getInstances(applicationName);
}


此时通过访问代理地址,并加上服务名称参数,接口获得服务信息
localhost:8800/service-instance/reservation-service
:



直接转发API调用请求

仅需在代理地址上加上服务名和API名称即可:
localhost:8800/reservation-service/reservations
即可,下图是原接口与代理调用接口的结果对比:



作为中间件处理调用数据

代理具有拦截并处理原接口数据的功能,实现方式即将代理自身定义为WEB服务接受请求后,在调用原微服务获取数据,再对数据进行处理后返回给客户端。事例代码如下:

@RestController
@RequestMapping("/reservations")
class ReservationApiGatewayRestController{

@Autowired
private DiscoveryClient discoveryClient;

//  @LoadBalanced
@Autowired
private RestTemplate restTemplate;

@RequestMapping("/names")
public Collection<String> getReservationNames(){
ParameterizedTypeReference<Resources<Reservation>> ptr =
new ParameterizedTypeReference<Resources<Reservation>>() { };
String url = discoveryClient.getInstances("reservation-service").get(0).getUri()+"/reservations";
ResponseEntity<Resources<Reservation>> responseEntity =
this.restTemplate.exchange(url,
HttpMethod.GET, null, ptr);
return responseEntity
.getBody()
.getContent()
.stream()
.map(Reservation::getReservationName)
.collect(Collectors.toList());
}

}


此例子将原接口返回的reservation实体处理后

,仅返回reservationName属性给客户端,达到保密隐藏其它属性的作用。调用结果如下:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息