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

一、微服务改造需求及技术选型

延迟任务系统进行微服务的改造,改造需求和技术选型。

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

目前主流两种方案:

1 基于dubbo协议的 将业务层封装成Dubbo接口供其他服务调用

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

**  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

二、延迟任务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

复制代码
package com.chongba.schedule.controller;
​
import com.chongba.entity.ResponseMessage;
import com.chongba.entity.Task;
import com.chongba.schedule.inf.TaskService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.*;
​
@Slf4j
@RestController
@RequestMapping("/task")
public class TaskController {
    
    @Autowired
    private TaskService taskService;
    
    @PostMapping("/push")
    public ResponseMessage pushTask(@RequestBody Task task){
        log.info("add task {}",task);
        try {
            //参数校验
            Assert.notNull(task.getTaskType(),"任务类型不能为空");
            Assert.notNull(task.getPriority(),"任务优先级不能为空");
            Assert.notNull(task.getExecuteTime(),"任务执行时间不能为空");
            Long taskId = taskService.addTask(task);
            return ResponseMessage.ok(taskId);
        }catch (Exception e){
            log.error("push task exception {}",task);
            return ResponseMessage.error(e.getMessage());
        }
    }
    
    @GetMapping("/poll/{type}/{priority}")
    public ResponseMessage pollTask(@PathVariable("type") Integer type, @PathVariable("priority") Integer priority){
        log.info("poll task {},{}",type,priority);
        try {
            Assert.notNull(type,"任务类型不能为空");
            Assert.notNull(priority,"任务优先级不能为空");
            Task task = taskService.poll(type, priority);
            return ResponseMessage.ok(task);
        } catch (Exception e) {
            log.error("poll task exception {},{}",type,priority);
            return ResponseMessage.error(e.getMessage());
        }
    }
    
    @PostMapping("/cancel")
    public ResponseMessage cancelTask(@RequestParam("taskId") Long taskId){
        log.info("cancel task {}",taskId);
        try {
            Assert.notNull(taskId,"任务id不能为空");
            boolean success = taskService.cancelTask(taskId);
            return ResponseMessage.ok(success);
        } catch (Exception e) {
            log.error("cancel task exception {}",taskId);
            return ResponseMessage.error(e.getMessage());
        }
​
    }
}

三、打开postman工具进行测试

测试添加任务接口需要传递一个json格式的对象数据,我们可以使用如下的代码来生成一个json数据而无需手动编写,在chongba_schedule_service工程中的测试包com.chongba.schedule下创建测试类TaskToJson,添加如下方法生成json数据,

复制代码
package com.chongba.schedule;
​
import com.alibaba.fastjson.JSON;
import com.chongba.entity.Task;
​
import java.util.Date;
​
public class TaskToJson {
    public static void main(String[] args) {
        Task task = new Task();
        task.setTaskType(1001);
        task.setPriority(1);
        task.setExecuteTime(new Date().getTime());
        System.out.println(JSON.toJSONString(task));
    }
}

测试1:添加方法测试,查看数据库和缓存中是否有任务数据!

打开Postman进行添加方法测试:

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

打开PostMan进行取消任务测试:

测试3:消费方法测试,查看缓存中的任务是否被消费,数据库中的数据状态!

打开PostMan进行消费方法测试