Spring Cloud学习笔记2——客户端服务调用及负载均衡
2017-11-28 16:16
555 查看
全部代码见:
注册中心(EurekaServer):https://gitee.com/wudiyong/EurekaServer.git
服务提供者(userInfoService):https://gitee.com/wudiyong/userInfoService.git
服务调用者(ribbonConsumer):https://gitee.com/wudiyong/ribbonConsumer.git
通过RestTemplate进行服务调用
在RestTemplate基础上加上负载均衡:
Ribbon是一个基于HTTP和TCP的负载均衡工具,可以让我们轻松的将面向服务的Rest模板请求自动转换成客户端负载均衡的服务调用。它不像注册中心、配置中心和网关那样需要独立部署,它几乎存在于每一个微服务应用中,因为微服务间的调用、网关的请求转发都需要用到ribbon。
2)创建一个被@LoadBalanced注解修饰的RestTemplate实例
可以在自定义的配置类中创建,但通常会放在入口类处(入口类本身也是一个配置类,因为@SpringBootApplication包含了@SpringBootConfiguration,@SpringBootConfiguration包含@Configuration),因为RestTemplate是一个与业务无关的基础bean。
3)调用服务
1)GET请求
GET请求有两种:getForEntity和getForObject
getForEntity:
该方法有3中重载实现,常用的是以下两种:
1、ResponseEntity<T> getForEntity(String url, Class<T> responseType, Map<String, ?> uriVariables)
2、ResponseEntity<T> getForEntity(String url, Class<T> responseType, Object... uriVariables)
第一个参数是请求的url,如果有参数,要写成如下方式:
http://USERINFO-SERVICE/userInfo?name={name}&age={age} 或 http://USERINFO-SERVICE/userInfo?name={1}&age={2}
第二个参数是返回类型,如,返回字符串则为String.class,返回UserPojo对象则是UserPojo.class
第三个参数是url中的参数值,第一种采用map的方式,第二种采用变长参数的方式,map方式中,通过key与{xxx}中的字符串xxx对应,变长方式中,{n}对应第n个变长参数,n从1开始。
该方法返回的是ResponseEntity对象,通过调用其getBody()方法可以返回与第二个参数类型相同的对象,如第二个参数是UserPojo.class,则getBody()返回UserPojo对象,如:
getForObject:
与getForEntity参数一样,只是返回值不同,getForObject直接返回与第二个参数相同的对象,即相当于getForEntity(....).getBody():
2)POST请求
POST请求也有两种:postForEntity和postForObject
getForEntity:
有三种实现,常用以下两种:
1、ResponseEntity<T> postForEntity(String url, Object request, Class<T> responseType, Object... uriVariables)
2、ResponseEntity<T> postForEntity(String url, Object request, Class<T> responseType, Map<String, ?> uriVariables)
其它参数与GET请求相同,只有第二个参数不一样,第二个参数可以是一个普通的对象,如UserPojo,也可以是一个HttpEntity对象,如果是普通对象,则该参数被当做成完整的body来处理,如果是HttpEntity对象,则该对象不仅包含body内容,还包含header内容。
第四个参数是用来对url中的参数进行绑定的,如果url中没有参数需要绑定,则可为空。
postForObject与getForEntity类似。
值得注意的是,POST请求发送json数据时,需要设置头部:
声明式服务调用Feign
声明式服务调用Feign,整合了RestTemplate(用于服务调用)、Ribbon(处理负载均衡)、Hystrix(服务容错保护)
代码:https://gitee.com/wudiyong/ribbonConsumer.git
1、引入Feign+Hystrix依赖
2、开启Feign及Hystrix功能
入口类加上如下注解:
@EnableFeignClients
@EnableHystrix也可以用feign.hystrix.enabled=true配置代替@EnableHystrix注解
3、创建调用远程服务的调用类
通常放在client包下,可以命名为RemoteServerName+Client
package com.ribbonConsumer.client;
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import com.ribbonConsumer.client.fallback.UserInfoClientFallback;
/*
* name:被调用服务的服务名
* fallback:调用失败之后的回调类
*/
@FeignClient(name = "userInfo-service", fallback = UserInfoClientFallback.class)
public interface UserInfoClient {
/**
* userInfo-service服务中的/userInfoStr接口
* 写法与被调用的接口一样,只是没有方法体
* 注意:
* 1、如果通过@RequestParam接收参数,一定要加上(value="xxx"),否则启动报错,
* 这是因为spring-cloud-feign处理@RequestParam和Spring mvc的不一样,
* Spring mvc在@RequestParam的value为空的时候会通过反射得到参数的名字作为value
* 如果通过@RequestBody接收map或某个对象,则与普通接口一样
*/
@RequestMapping(value = "/userInfoStr", method = RequestMethod.GET)
public String userInfoStr(@RequestParam(value = "name") String name, @RequestParam(value = "age") String age);
}
4、创建调用失败的回调类
回调类是实现调用接口的一个普通类,没有任何特别,该类只有在调用失败的时候会被调用,如果请求能到达远程服务,只是远程服务返回一些错误信息,这种情况不属于调用失败,调用失败如网络不通、服务不可用情况
package com.ribbonConsumer.client.fallback;
import org.springframework.stereotype.Component;
import com.ribbonConsumer.client.UserInfoClient;
@Component
public class UserInfoClientFallback implements UserInfoClient{
@Override
public String userInfoStr(String name, String age) {
return "调用失败";
}
}
至此,Hystrix配置完成,可以开始测试了
可以在controller上加上如下代码用于测试:
@Autowired
private UserInfoClient userInfoClient;
/**
* 使用Feign方式调用服务
*/
@RequestMapping(value = "/userInfoStr", method = RequestMethod.GET)
public String userInfoStr(@RequestParam String name, @RequestParam String age){
return userInfoClient.userInfoStr(name, age);
}
可以分别测试userInfo-service服务可用和不可用两种情况
注册中心(EurekaServer):https://gitee.com/wudiyong/EurekaServer.git
服务提供者(userInfoService):https://gitee.com/wudiyong/userInfoService.git
服务调用者(ribbonConsumer):https://gitee.com/wudiyong/ribbonConsumer.git
通过RestTemplate进行服务调用
在RestTemplate基础上加上负载均衡:Ribbon是一个基于HTTP和TCP的负载均衡工具,可以让我们轻松的将面向服务的Rest模板请求自动转换成客户端负载均衡的服务调用。它不像注册中心、配置中心和网关那样需要独立部署,它几乎存在于每一个微服务应用中,因为微服务间的调用、网关的请求转发都需要用到ribbon。
1、使用Ribbon实现负载均衡调用只需3步:
1)在pom.xml文件中加入Ribbon依赖<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-ribbon</artifactId> </dependency>
2)创建一个被@LoadBalanced注解修饰的RestTemplate实例
可以在自定义的配置类中创建,但通常会放在入口类处(入口类本身也是一个配置类,因为@SpringBootApplication包含了@SpringBootConfiguration,@SpringBootConfiguration包含@Configuration),因为RestTemplate是一个与业务无关的基础bean。
@Bean @LoadBalanced RestTemplate restTemplate() { return new RestTemplate(); }
3)调用服务
@RestController public class ConsumerController { @Autowired RestTemplate restTemplate; @RequestMapping(value="/userInfo", method = RequestMethod.GET) public String userInfo(@RequestParam String name, @RequestParam String age) { //如果是post请求,可以用postForEntity Map<String , Object> params = new HashMap<String , Object>(); params.put("name", name); params.put("age", age); return restTemplate.getForEntity("http://USERINFO-SERVICE/userInfo?name={name}&age={age}", String.class,params).getBody(); } }
2、各种调用服务的方法
1)GET请求GET请求有两种:getForEntity和getForObject
getForEntity:
该方法有3中重载实现,常用的是以下两种:
1、ResponseEntity<T> getForEntity(String url, Class<T> responseType, Map<String, ?> uriVariables)
2、ResponseEntity<T> getForEntity(String url, Class<T> responseType, Object... uriVariables)
第一个参数是请求的url,如果有参数,要写成如下方式:
http://USERINFO-SERVICE/userInfo?name={name}&age={age} 或 http://USERINFO-SERVICE/userInfo?name={1}&age={2}
第二个参数是返回类型,如,返回字符串则为String.class,返回UserPojo对象则是UserPojo.class
第三个参数是url中的参数值,第一种采用map的方式,第二种采用变长参数的方式,map方式中,通过key与{xxx}中的字符串xxx对应,变长方式中,{n}对应第n个变长参数,n从1开始。
该方法返回的是ResponseEntity对象,通过调用其getBody()方法可以返回与第二个参数类型相同的对象,如第二个参数是UserPojo.class,则getBody()返回UserPojo对象,如:
ResponseEntity<UserPojo> responseEntity = restTemplate.getForEntity( "http://USERINFO-SERVICE/userInfo?name={1}&age={2}", UserPojo.class,"谢谢谢","12"); UserPojo userPojo = responseEntity.getBody();
getForObject:
与getForEntity参数一样,只是返回值不同,getForObject直接返回与第二个参数相同的对象,即相当于getForEntity(....).getBody():
UserPojo userPojo = restTemplate.getForObject( "http://USERINFO-SERVICE/userInfo?name={name}&age={age}", UserPojo.class,params);
2)POST请求
POST请求也有两种:postForEntity和postForObject
getForEntity:
有三种实现,常用以下两种:
1、ResponseEntity<T> postForEntity(String url, Object request, Class<T> responseType, Object... uriVariables)
2、ResponseEntity<T> postForEntity(String url, Object request, Class<T> responseType, Map<String, ?> uriVariables)
其它参数与GET请求相同,只有第二个参数不一样,第二个参数可以是一个普通的对象,如UserPojo,也可以是一个HttpEntity对象,如果是普通对象,则该参数被当做成完整的body来处理,如果是HttpEntity对象,则该对象不仅包含body内容,还包含header内容。
第四个参数是用来对url中的参数进行绑定的,如果url中没有参数需要绑定,则可为空。
postForObject与getForEntity类似。
值得注意的是,POST请求发送json数据时,需要设置头部:
RestTemplate restTemplate = new RestTemplate(); HttpHeaders headers = new HttpHeaders(); MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8"); headers.setContentType(type); headers.add("Accept", MediaType.APPLICATION_JSON.toString()); HttpEntity<String> formEntity = new HttpEntity<String>(requestJsonStr, headers); String jsonStr = restTemplate.postForEntity(url, formEntity,String.class).getBody();
声明式服务调用Feign
声明式服务调用Feign,整合了RestTemplate(用于服务调用)、Ribbon(处理负载均衡)、Hystrix(服务容错保护)代码:https://gitee.com/wudiyong/ribbonConsumer.git
1、引入Feign+Hystrix依赖
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-feign</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-hystrix</artifactId> </dependency>
2、开启Feign及Hystrix功能
入口类加上如下注解:
@EnableFeignClients
@EnableHystrix也可以用feign.hystrix.enabled=true配置代替@EnableHystrix注解
3、创建调用远程服务的调用类
通常放在client包下,可以命名为RemoteServerName+Client
package com.ribbonConsumer.client;
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import com.ribbonConsumer.client.fallback.UserInfoClientFallback;
/*
* name:被调用服务的服务名
* fallback:调用失败之后的回调类
*/
@FeignClient(name = "userInfo-service", fallback = UserInfoClientFallback.class)
public interface UserInfoClient {
/**
* userInfo-service服务中的/userInfoStr接口
* 写法与被调用的接口一样,只是没有方法体
* 注意:
* 1、如果通过@RequestParam接收参数,一定要加上(value="xxx"),否则启动报错,
* 这是因为spring-cloud-feign处理@RequestParam和Spring mvc的不一样,
* Spring mvc在@RequestParam的value为空的时候会通过反射得到参数的名字作为value
* 如果通过@RequestBody接收map或某个对象,则与普通接口一样
*/
@RequestMapping(value = "/userInfoStr", method = RequestMethod.GET)
public String userInfoStr(@RequestParam(value = "name") String name, @RequestParam(value = "age") String age);
}
4、创建调用失败的回调类
回调类是实现调用接口的一个普通类,没有任何特别,该类只有在调用失败的时候会被调用,如果请求能到达远程服务,只是远程服务返回一些错误信息,这种情况不属于调用失败,调用失败如网络不通、服务不可用情况
package com.ribbonConsumer.client.fallback;
import org.springframework.stereotype.Component;
import com.ribbonConsumer.client.UserInfoClient;
@Component
public class UserInfoClientFallback implements UserInfoClient{
@Override
public String userInfoStr(String name, String age) {
return "调用失败";
}
}
至此,Hystrix配置完成,可以开始测试了
可以在controller上加上如下代码用于测试:
@Autowired
private UserInfoClient userInfoClient;
/**
* 使用Feign方式调用服务
*/
@RequestMapping(value = "/userInfoStr", method = RequestMethod.GET)
public String userInfoStr(@RequestParam String name, @RequestParam String age){
return userInfoClient.userInfoStr(name, age);
}
可以分别测试userInfo-service服务可用和不可用两种情况
相关文章推荐
- osgi学习笔记4之 web客户端调用已发布的接口服务
- spring cloud学习笔记2(负载均衡ribbon,服务容错保护Hystrix)
- Android(java)学习笔记229:服务(service)之绑定服务调用服务里面的方法 (采用接口隐藏代码内部实现)
- WebService学习2:服务端发布服务、客户端调用服务
- [笔记-架构探险]web服务框架-cxf-4.1.多种方式的发布与客户端调用
- Android(java)学习笔记228:服务(service)之绑定服务调用服务里面的方法
- 学习笔记之ArcGIS Engine调用自定义GP服务(二)
- 学习Axis2笔记之四--创建pojo服务和客户端
- spring cloud,用feign客户端调用服务hystrix不能生效的问题
- 学习笔记之ArcGIS Engine调用自定义GP服务(亲测!!!)(二)
- Androidx学习笔记(71)--- 需要支付的应用(调用远程的服务)
- 06.Spring Cloud学习笔记之声明式服务调用组件Feign
- solr学习笔记(3)--使用solrj调用solr服务
- 调用webservice服务(二) 学习笔记/cxf拦截器
- 一步一个脚印学习WCF之一WCF概要(中)之客户端与服务-WCF服务的创建与调用Demo
- android 学习笔记9-服务 启动停止 调用服务方法 远程服务 AIDL进程通信
- ASP.NET MVC 学习笔记-2.Razor语法 ASP.NET MVC 学习笔记-1.ASP.NET MVC 基础 反射的具体应用 策略模式的具体应用 责任链模式的具体应用 ServiceStack.Redis订阅发布服务的调用 C#读取XML文件的基类实现
- WeX5学习笔记之调用后端服务
- spring cloud快速入门教程(六)进程间调用和微服务负载均衡(Feign)
- Mule ESB 学习笔记 服务调用