我是靠谱客的博主 留胡子美女,最近开发中收集的这篇文章主要介绍SpringCloud 通过继承 HystrixCollapser 实现请求合并,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

1. 消费端 service 代码:

package com.service;
import java.util.List;
import com.model.User;
public interface UserService {
public User find(Long id);
public List<User> findAll(List<Long> ids);
}

 

package com.serviceImpl;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import com.ctc.wstx.util.StringUtil;
import com.model.User;
import com.service.UserService;
import org.apache.commons.collections.map.HashedMap;
import org.apache.commons.lang3.StringUtils;
@Service
public class UserServiceImpl implements UserService {
@Autowired
private RestTemplate restTemplate;
@Override
public User find(Long id) {
return restTemplate.getForObject("http://hello-service/users/{1}",User.class,id);
}
@Override
public List<User> findAll(List<Long> ids) {
System.out.println("UserService findAll()");
//RestTemplate restTemplate2 = new RestTemplate();
//List<User> listUser2 = new ArrayList<>();
User[] users =
restTemplate.getForObject("http://hello-service/users?ids={1}",User[].class,
StringUtils.join(ids,","));
//User[] users =
restTemplate2.getForObject("http://localhost:8090/users?ids={1}",User[].class,
//
StringUtils.join(ids,","));
//listUser2 =
Arrays.asList(users);
/*System.out.println("listUser2.size():" + listUser2.size());
Integer integer=1;
for (User user : listUser2) {
System.out.println("UserID:" + user.getId());
System.out.println("UserName:" + user.getName());
System.out.println("UserXingBie:" + user.getXingBie());
System.out.println("integer:" + integer);
integer=integer+1;
}
System.out.println("==================================================");
for (int i = 0; i < listUser2.size(); i++) {
System.out.println("UserID:" + listUser2.get(i).getId());
System.out.println("UserName:" + listUser2.get(i).getName());
System.out.println("UserXingBie:" + listUser2.get(i).getXingBie());
System.out.println("integer:" + i);
}*/
return
Arrays.asList(users);
//return listUser2;
}
}

 

2. 消费端 UserBatchCommand 类

package com.support;
import java.util.ArrayList;
import java.util.List;
import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
import org.springframework.beans.factory.annotation.Autowired;
import com.model.User;
import com.netflix.hystrix.HystrixCommand;
import com.netflix.hystrix.HystrixCommandGroupKey;
import com.service.UserService;
import com.serviceImpl.UserServiceImpl;
import scala.sys.process.processInternal;
public class UserBatchCommand extends HystrixCommand<List<User>> {
@Autowired
private UserService userService;
private List<Long> userIds;
public UserBatchCommand(UserService userService,
List<Long> userIds) {
super(Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("userServiceCommand")));
this.userIds = userIds;
this.userService = userService;
}
@Override
protected List<User> run() throws Exception {
System.out.println("UserBatchCommand run():" + userIds.get(0) +"
" + userIds.get(1));
return userService.findAll(userIds);
}
public static void main(String[] args) throws Exception {
List<Long> list = new ArrayList<>();
UserService userService =
new UserServiceImpl();
list.add(1L);
list.add(2L);
UserBatchCommand userBatchCommand = new UserBatchCommand(userService,list);
List<User> listUser = new ArrayList<>();
listUser=userBatchCommand.run();
}
}

 

3. 消费端 UserCollapseCommand 类

package com.support;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;
import com.model.*;
import com.netflix.hystrix.HystrixCollapser;
import com.netflix.hystrix.HystrixCollapserKey;
import com.netflix.hystrix.HystrixCollapserProperties;
import com.netflix.hystrix.HystrixCommand;
import com.netflix.hystrix.HystrixCommandGroupKey;
//import com.netflix.hystrix.HystrixCommand.Setter;
import com.service.UserService;
public class UserCollapseCommand extends HystrixCollapser<List<User>, User, Long> {
private UserService userService;
private Long userId;
public UserCollapseCommand(UserService userService,Long userId) {
super(Setter.withCollapserKey(HystrixCollapserKey.Factory.asKey("userCollapseCommand"))
.andCollapserPropertiesDefaults(
HystrixCollapserProperties.Setter()
.withTimerDelayInMilliseconds(100)));
this.userService = userService;
this.userId = userId;
}
@Override
public Long getRequestArgument() {
return userId;
}
@Override
protected HystrixCommand<List<User>>
createCommand(Collection<CollapsedRequest<User, Long>>
collapsedRequests) {
List<Long> userIds = new ArrayList<>(collapsedRequests.size());
userIds.addAll(collapsedRequests.stream().map(CollapsedRequest::getArgument).collect(
Collectors.toList()));
return new UserBatchCommand(userService, userIds);
}
@Override
protected void mapResponseToRequests(List<User> batchResponse,
Collection<CollapsedRequest<User, Long>> collapsedRequests) {
System.out.println("mapResponseToRequests========>");
int count = 0;
for (CollapsedRequest<User, Long> collapsedRequest:collapsedRequests) {
User user = batchResponse.get(count++);
collapsedRequest.setResponse(user);
}
}
}

 

4. 消费端 Controller 

package com.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.model.User;
import com.netflix.hystrix.strategy.concurrency.HystrixRequestContext;
//import com.netflix.hystrix.strategy.concurrency.HystrixRequestContext;
import com.service.UserService;
import com.support.UserCollapseCommand;
import java.util.ArrayList;
import java.util.List;
//import com.support.UserCollapseCommand;
//import ch.qos.logback.core.Context;
import java.util.concurrent.Future;
@RestController
public class CollapseCommandController2 {
@Autowired
private UserService userService;
@RequestMapping(value="/collapse2",method = RequestMethod.GET)
public List<User> requestCollapse(@RequestParam(value="ids") List<Long> ids) {
List<User> listUser = new ArrayList<>();
System.out.println("CollapseCommandController requestCollapse 方法");
//HystrixRequestContext context = HystrixRequestContext.initializeContext();
List<Future<User>> futures = new ArrayList<Future<User>>();
for(Long id : ids) {
UserCollapseCommand userCollapseCommand =
new UserCollapseCommand(userService,id);
futures.add(userCollapseCommand.queue());
}
try {
for(Future<User> future : futures) {
System.out.println("CacheController的结果:" + future.get());
listUser.add(future.get());
}
} catch (Exception e) {
e.printStackTrace();
}
return listUser;
}
}

 

5. 消费端过滤器,注意我们在过滤器中初始化 HystrixRequestContext (Hystrix 请求上下文),如果没有初始化Hystrix请求上下文会报错。

package com.example.server1;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import com.netflix.hystrix.strategy.concurrency.HystrixRequestContext;
public class HystrixRequestContextServletFilter implements Filter {
private Integer i = 0;
private HystrixRequestContext context;
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
//if(i==0) {
System.out.println("过滤器");
context = HystrixRequestContext.initializeContext();
// i++;
// }
try {
chain.doFilter(request, response);
} finally {
context.shutdown();
}
}
@Override
public void destroy() {
// TODO Auto-generated method stub
}
@Override
public void init(FilterConfig arg0) throws ServletException {
// TODO Auto-generated method stub
}
}

6. 消费端 Bean 配置类。注意 Bean配置文件需要与 SpringBoot 工程主类放在同一个包下,不然扫描步到 Bean 配置文件,无法加载配置的Bean 。

package com.example.server1;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.controller.CollapseCommandController;
import com.controller.CollapseCommandController2;
import com.controller.ListUserColltroller;
import com.controller.TestController2;
import com.serviceImpl.UserServiceImpl;
import com.support.UserBatchCommand;
import com.service.UserService;
@Configuration
public class WebComponent2Config {
@Bean
public FilterRegistrationBean someFilterRegistration1() {
//新建过滤器注册类
FilterRegistrationBean registration = new FilterRegistrationBean();
// 添加我们写好的过滤器
registration.setFilter( new HystrixRequestContextServletFilter());
// 设置过滤器的URL模式
registration.addUrlPatterns("/*");
return registration;
}
@Bean
TestController2 testController2() {
return new TestController2();
}
@Bean
CollapseCommandController collapseCommandController() {
return new CollapseCommandController();
}
@Bean
UserService userService() {
return new UserServiceImpl();
}
@Bean
CollapseCommandController2 collapseCommandController2() {
return
new CollapseCommandController2();
}
@Bean
ListUserColltroller listUserColltroller() {
return new ListUserColltroller();
}
}

 

7. 服务端 Controller 

package com.controller;
import java.io.LineNumberInputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.apache.log4j.Logger;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.model.User;
@RestController
public class UserController {
private final Logger logger = Logger.getLogger(UserController.class);
@RequestMapping(value="/users",method = RequestMethod.GET)
public List<User> index(@RequestParam(value="ids") List<Long> ids) throws Exception {
//System.out.println("hell-service UserService :");
List<User> listUser = new ArrayList<User>();
for (Long long1 : ids) {
User user = new User();
user.setId(long1);
user.setName("lixia"+long1);
user.setXingBie("男");
listUser.add(user);
/*System.out.println("long1:" + long1);
System.out.println("userID:"+ user.getId());
System.out.println("userID:"+ user.getName());
System.out.println("userID:"+ user.getXingBie());*/
System.out.println("long1:" + long1);
Integer integer = 0;
System.out.println("userID:"+ listUser.get(integer).getId());
System.out.println("userID:"+ listUser.get(integer).getName());
System.out.println("userID:"+ listUser.get(integer).getXingBie());
integer++;
}
System.out.println("listUser.size():" +listUser.size());
/*System.out.println("userID:"+ listUser.get(2).getId());
System.out.println("userID:"+ listUser.get(2).getName());
System.out.println("userID:"+ listUser.get(2).getXingBie());*/
//System.out.println("user:" + listUser.get(0).getId() + " " + listUser.get(0).getName() +" "+ listUser.get(0).getXingBie());
//System.out.println("user2:" + listUser.get(1).getId() + " " + listUser.get(1).getName() +" "+ listUser.get(1).getXingBie());
return listUser;
}
}

 

8. 服务端 Bean 配置类。注意 Bean配置文件需要与 SpringBoot 工程主类放在同一个包下,不然扫描步到 Bean 配置文件,无法加载配置的Bean 。

package com.example.server1;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.request;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.controller.*;
@Configuration
public class WebComponent2Config {
@Bean
UserController userController() {
return new UserController();
}
}

 

8. 通过浏览器访问消费端 Controller 进行测试

 

9. Hystrix 的请求合并功能非常鸡肋,只能在一次请求消费端的 Controller 中多次请求 service 时进行请求合并,不能在对多次请求消费端的 Controller 进行合并。如果只想在消费端的 Controller 代码中实现一次请求获取多个对象,直接用消费端 Controller 通过传 List 参数直接调用消费端 service 就可以实现了。

消费端直接批量调用 service 的 Controller 的方式编码比 Hystrix 请求合并少。

消费端直接批量调用 service 的 Controller 代码:

package com.controller;
import java.util.List;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.model.User;
import com.service.UserService;
import scala.unchecked;
@RestController
public class ListUserColltroller {
private final Logger logger = Logger.getLogger(ListUserColltroller.class);
@Autowired
private UserService userService;
@RequestMapping(value="/listUser",method = RequestMethod.GET)
public List<User> requestCollapse(@RequestParam(value="ids") List<Long> ids) {
System.out.println("/listUser");
return userService.findAll(ids);
}
}

 

测试:

最后

以上就是留胡子美女为你收集整理的SpringCloud 通过继承 HystrixCollapser 实现请求合并的全部内容,希望文章能够帮你解决SpringCloud 通过继承 HystrixCollapser 实现请求合并所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(50)

评论列表共有 0 条评论

立即
投稿
返回
顶部