找回密码
 立即注册
首页 业界区 业界 虚拟电商-延迟任务系统的微服务改造(一)改造需求及技 ...

虚拟电商-延迟任务系统的微服务改造(一)改造需求及技术选型

敖可 4 天前
一、微服务改造需求及技术选型


  延迟任务系统进行微服务的改造,改造需求和技术选型。
  虽然程序目前做了各种优化,接口的缓存优化,接口的线程优化,但它还是单机版,所以需要改造成微服务(分布式),对于分布式而言,分布式本质是进程之间通信,和服务治理(比如服务的注册与发现,服务的降级,服务的容错)。
1.png

 

目前主流两种方案:
  1 基于dubbo协议的 将业务层封装成Dubbo接口供其他服务调用
 
2.png

 
  2 基于http协议的 springcloud 全家桶封装成微服务
 
3.png

 
  tcp ,http 性能哪个高?
  tcp性能高,http是基于tcp的应用层协议
  dubbo 和springcloud 区别?

  1:Spring Cloud抛弃了Dubbo 的RPC通信,采用的是基于HTTP的REST方式。严格来说,这两种方式各有优劣。虽然在一定程度上来说,后者牺牲了服务调用的性能,但也避免了上面提到的原生RPC带来的问题。而且REST相比RPC更为灵活,服务提供方和调用方的依赖只依靠一纸契约,不存在代码级别的强依赖,这在强调快速演化的微服务环境下,显得更为合适。
  2:Dubbo和Spring Cloud并不是完全的竞争关系,两者所解决的问题域不一样:Dubbo的定位始终是一款RPC框架,而Spring Cloud的目的是微服务架构下的一站式解决方案。
  3:非要比较的话,Dubbo可以类比到Netflix OSS技术栈,而Spring Cloud集成了Netflix OSS作为分布式服务治理解决方案,但除此之外Spring Cloud还提供了包括config、stream、security、sleuth等分布式服务解决方案。当前由于RPC协议、注册中心元数据不匹配等问题,在面临微服务基础框架选型时Dubbo与Spring Cloud只能二选一,这也是两者总拿来做对比的原因。Dubbo之后会积极寻求适配到Spring Cloud生态,比如作为SpringCloud的二进制通讯方案来发挥Dubbo的性能优势,或者Dubbo通过模块化以及对http的支持适配到Spring Cloud
 
4.png

 
二、延迟任务web层接口开发


  对比了当前比较流行的两套微服务技术解决方案。通过对比的结果我们发现,Dubbo在很多领域,这个解决方案其实并不完善,因此在延迟任务系统进行微服务改造的时候。 我们选择基于http协议的springcloud全家桶封装成微服务。这种形式我们开发起来比较顺手,因为springcloud是基于Http协议,进行服务之间调用的,说白了开发起来就相当于,开发传统的SSM项目,我们只需要编写controller、service以及我们的mapper,有了controller之后我们就可以使用Http进行调用。我们来开发web层接口 ( controller接口)。
  应用技术: SpringBoot, SpringCloud,Consul ,Redis ,MySQL , Feign, Junit , PostMan
  1:统一Controller接口的返回数据格式,在chongba_common的com.chongba.entity包下添加如下两个类:
此处返回结果代码。
  2:在chongba__schedule_service中创建包:com.chongba.schedule.controller 在该包下创建TaskCtroller类,依次编写:添加任务,消费任务,取消任务的方法
添加任务:pushTask
消费任务:pollTask
取消任务:cancelTask
 
  1. package com.chongba.schedule.controller;
  2. import com.chongba.entity.ResponseMessage;
  3. import com.chongba.entity.Task;
  4. import com.chongba.schedule.inf.TaskService;
  5. import lombok.extern.slf4j.Slf4j;
  6. import org.springframework.beans.factory.annotation.Autowired;
  7. import org.springframework.util.Assert;
  8. import org.springframework.web.bind.annotation.*;
  9. @Slf4j
  10. @RestController
  11. @RequestMapping("/task")
  12. public class TaskController {
  13.    
  14.     @Autowired
  15.     private TaskService taskService;
  16.    
  17.     @PostMapping("/push")
  18.     public ResponseMessage pushTask(@RequestBody Task task){
  19.         log.info("add task {}",task);
  20.         try {
  21.             //参数校验
  22.             Assert.notNull(task.getTaskType(),"任务类型不能为空");
  23.             Assert.notNull(task.getPriority(),"任务优先级不能为空");
  24.             Assert.notNull(task.getExecuteTime(),"任务执行时间不能为空");
  25.             Long taskId = taskService.addTask(task);
  26.             return ResponseMessage.ok(taskId);
  27.         }catch (Exception e){
  28.             log.error("push task exception {}",task);
  29.             return ResponseMessage.error(e.getMessage());
  30.         }
  31.     }
  32.    
  33.     @GetMapping("/poll/{type}/{priority}")
  34.     public ResponseMessage pollTask(@PathVariable("type") Integer type, @PathVariable("priority") Integer priority){
  35.         log.info("poll task {},{}",type,priority);
  36.         try {
  37.             Assert.notNull(type,"任务类型不能为空");
  38.             Assert.notNull(priority,"任务优先级不能为空");
  39.             Task task = taskService.poll(type, priority);
  40.             return ResponseMessage.ok(task);
  41.         } catch (Exception e) {
  42.             log.error("poll task exception {},{}",type,priority);
  43.             return ResponseMessage.error(e.getMessage());
  44.         }
  45.     }
  46.    
  47.     @PostMapping("/cancel")
  48.     public ResponseMessage cancelTask(@RequestParam("taskId") Long taskId){
  49.         log.info("cancel task {}",taskId);
  50.         try {
  51.             Assert.notNull(taskId,"任务id不能为空");
  52.             boolean success = taskService.cancelTask(taskId);
  53.             return ResponseMessage.ok(success);
  54.         } catch (Exception e) {
  55.             log.error("cancel task exception {}",taskId);
  56.             return ResponseMessage.error(e.getMessage());
  57.         }
  58.     }
  59. }
复制代码
 
 
三、打开postman工具进行测试


  测试添加任务接口需要传递一个json格式的对象数据,我们可以使用如下的代码来生成一个json数据而无需手动编写,在chongba_schedule_service工程中的测试包com.chongba.schedule下创建测试类TaskToJson,添加如下方法生成json数据,
 
  1. package com.chongba.schedule;
  2. import com.alibaba.fastjson.JSON;
  3. import com.chongba.entity.Task;
  4. import java.util.Date;
  5. public class TaskToJson {
  6.     public static void main(String[] args) {
  7.         Task task = new Task();
  8.         task.setTaskType(1001);
  9.         task.setPriority(1);
  10.         task.setExecuteTime(new Date().getTime());
  11.         System.out.println(JSON.toJSONString(task));
  12.     }
  13. }
复制代码
 
 
  测试1:添加方法测试,查看数据库和缓存中是否有任务数据!
打开Postman进行添加方法测试:
5.png

 



  测试2:取消任务测试,先运行一下添加方法保证系统中有任务,然后在测试取消,查看任务是否被取消!
打开PostMan进行取消任务测试:
6.png

 



  测试3:消费方法测试,查看缓存中的任务是否被消费,数据库中的数据状态!
打开PostMan进行消费方法测试
 
7.png

 




来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
您需要登录后才可以回帖 登录 | 立即注册