用Spring Cloud和异步微服务进行无服务器计算
什么是无服务器计算?
无服务器并不意味着您的服务在没有服务器的情况下运行。您肯定需要一个计算层来运行您的服务。无服务器只是意味着您可以在不配置或管理服务器的情况下运行代码。AWS Lambda就是无服务器计算服务的一个这样的例子。AWS Lambda将仅在需要时执行您的代码,自动扩展,并且在代码未运行时您不会专用计算能力,这意味着成本更低。
无服务框架(关键部分)
对于任何无服务器程序,大致有三个部分:
- 事件/触发器:事件可以是文件上载,数据库更新,HTTP请求或您可以想到的任何其他您希望功能/服务执行的操作。例如,一旦用户在目录中上传文件,您可能希望创建多种格式的视频文件
- 任务/功能:事件发生后,需要进行一些工作。任务是编写程序逻辑来完成这项工作的地方。
- 任务启动平台:生成事件后,平台将捕获事件并启动与该事件关联的任务。AWS Lambda就是这样一个平台的一个例子,它可以为您管理这样的管道。同样,Spring Cloud也提供了经典的Spring注释格式的结构来运行这样的程序。
在下面的示例中,我将向您介绍如何使用Spring Cloud构建无服务器的异步任务。
在我们的示例中,用户POST一个Web请求以运行蓝色任务或红色任务。这些基本任务打印出参数,用户作为POST请求体的一部分发出。
示例如下图所示。该图还将各种组件映射到我上面描述的无服务器框架。
让我们看看各个部分和相关的Spring Cloud管道代码。
1
通过HTTP POST请求触发事件
用户发送一个HTTP POST请求,请求正文中包含一些虚拟文本。我们也可以使用任何其他事件触发器,例如文件上传、数据库更新等。为了便于演示,我选择了一个HTTP触发器。网址如下:http://localhost:8080/tasks/color。颜色路径变量可以是“红色”或“蓝色”,表示是运行redtask还是bluetask。
2
RestController
用户请求被标准的Spring RestController捕获。我们使用标准的@RestController注释我们的类来启用行为:
// Rest Controller intercepts the user POST request @RestController public class TaskTriggerController { @Autowired private TaskProcessor t; @RequestMapping(path = "/tasks/{color}", method = RequestMethod.POST) public @ResponseBody String launchTask(@RequestBody String s, @PathVariable String color) { // delegates responsibility of putting task request on queue to TaskProcessor bean t.publishRequest(s, color); } // method ends } // class ends
3
任务处理器
该bean的唯一目的是将任务启动请求放入队列中。我们在类的顶部使用标准的@Component注释。为了将类绑定到队列,我使用了@EnableBinding批注。除此之外,您还需要指定RabbitMQ属性。队列名称是消息发布的位置:
@Component @EnableBinding(Source.class) public class TaskProcessor { @Autowired private Source source; ...... }
4
任务启动请求
任务存储在Maven存储库中。此外,任务启动需要Maven URL作为输入。maven URL格式显示为maven:// [groupid]:[artifactid]:jar:[version]。URL中的Groupid,artifactid和版本是我们在Task的pom.xml中指定的值。
任务启动请求的另一个参数是我们要为任务提供的输入。以下代码缩写为:
public class TaskProcessor { .... public void publishRequest(String payload, String color) { String redUrl = "maven://gauravg.springclouddemo:springcloud-red-task:jar:0.0.1-SNAPSHOT"; TaskLaunchRequest request = new TaskLaunchRequest(redUrl, input, null, null); GenericMessage < TaskLaunchRequest > message = new GenericMessage < > (request); // this call places the message on queue this.source.output().send(message); .... } // method ends } // class ends
5
任务启动器
任务启动器使用队列上发布的消息。然后,启动程序使用消息中提供的Maven存储库和Maven URL来启动请求。@EnableTaskLauncher注释使Boot应用程序成为我们的任务启动器。另外,我们必须在application.properties文件中指定RabbitMQ属性,类似于我上面描述的。
@SpringBootApplication @EnableTaskLauncher public class TaskLauncherApplication { public static void main(String[] args) { SpringApplication.run(TaskLauncherApplication.class, args); } }
6
Spring Cloud任务
Spring Cloud Task是一个短命的异步微服务,可以实现真正的动作。在我们的示例中,这些是蓝色/红色任务。这些任务是Spring Boot应用程序。作为Spring Boot应用程序,它还可以访问Spring容器中的各种bean,还可以订阅各种生命周期事件。
Spring提供@EnableTask注释,用于将Boot应用程序分类为云任务。业务逻辑将在Runner中编写,您可以使用多个运行程序。所有跑步者完成后,任务将完成。
在完成任务逻辑之后,只需运行 maven –install 将任务放入存储库
@SpringBootApplication @EnableTask public class RedTaskApplication { public class RedTask implements CommandLineRunner { ..... @Override public void run(String...strings) throws Exception { // Task logic goes here } // method ends } // class ends } // boot class ends
7
执行历史
每个任务执行生成任务执行历史。此历史记录保存在数据库中,该数据库在application.properties中为任务配置。Spring Cloud Task生成多个表。要查看的关键表是task_execution和task_execution_params。这些表包含任务状态和提交任务执行的参数。
spring.datasource.url=jdbc:mysql://localhost/tasklogs spring.datasource.username=root spring.datasource.password=root spring.datasource.driver-class-name=com.mysql.jdbc.Driver
在典型的设置中,红色和蓝色任务都将作为服务部署在专用容器中。但是,Spring Cloud使我们无需专用服务器即可运行这些任务。AWS Lambda等服务隐藏了这种平台的螺母和螺栓。希望这个例子能让您深入了解无服务器机制以及如何使用Spring Cloud构建这样一个平台。
end:如果你觉得本文对你有帮助的话,记得点赞转发,你的支持就是我更新动力。