前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >不单独部署注册中心,又要具备注册中心的功能,咋不让我上天?

不单独部署注册中心,又要具备注册中心的功能,咋不让我上天?

作者头像
青石路
发布2024-07-02 08:21:21
720
发布2024-07-02 08:21:21
举报
文章被收录于专栏:开发技术

需求描述

一天,领导找到我,巴拉巴拉一顿沟通,需求很清晰,我就不细说了(因为跟本文关系不大),总结下就是

有两个服务:任务分发中心、任务执行器 分发中心负责任务拆分,然后将拆分后的任务下发给执行器,执行器执行任务 任务分发中心和任务执行器都要支持水平扩节点

我说:技术实现没什么难点,引入注册中心就行

但领导紧接着就说:考虑到客户硬件资源的局限性以及部署的复杂性,不能单独部署注册中心

当时我就懵了,心里想的是

既要马儿跑,又要马儿不吃草,咋不让我上天?

工作要紧
工作要紧

我接着说道:任务分发中心兼职注册中心,任务执行器能够自动注册到分发中心?

领导:对,你总结的言简意赅,就是要实现这样的效果

领导又补充道:你可以简单点实现,不用像 Nacos 那样复杂,服务支持水平扩展,能够监控任务执行器状态就行

相信大家都明白需求了,总结成一句话

拿着卖白菜的钱,要干卖白粉的事!

需求实现

主流的注册中心,像ZookeeperNacosetcd、Consul 以及 Eureka,都需要单独部署;如果能单独部署,那实现就简单了,可现在要求是不能单独部署,但又要有注册中心的基本功能

宝宝心里苦
宝宝心里苦

说白了,就是要自实现一个简易版的注册中心,虽说是简易版,但基本功能还是要有吧

  1. 服务发现 注册中心存储和管理所有可用服务的地址信息,其他服务可以通过查询注册中心发现所需的服务
  2. 服务注册 服务提供者可以将自己的地址信息注册到注册中心,以便其他服务发现和调用
  3. 健康检查 注册中心定期对注册的服务进行健康检查,以确保服务的可用性 某个服务出现故障或不可用,注册中心能够将其从可用服务列表中移除,防止其他服务调用失败
  4. 支持水平拓展 注册中心肯定要支持水平拓展来保障其高可用 注册中心节点之间要能正常通信,节点之间的可用服务列表能够及时同步,并且要保证一致

这些基本功能实现起来简不简单?也许你们觉的简单,可我觉的并不简单

但事已至此,已无退路,只能硬着头皮上了

分发中心集成 Eureka Server

几个主流的注册中心,我对 Eureka 比较熟悉,感觉其实现还算比较简单,参考它来实现注册中心应该可行

一头扎进去看源码,一天下来收效甚微,发现并非想象中的那么简单,正当我准备放弃时,脑中闪过一个念头

任务分发中心可不可以集成 Eureka Server?

Eureka Server 是注册中心,这个我们都知道,但我们忽略了一个点,它还是一个普通 Web 服务,只是我们平时不用它来处理业务请求,仅仅是把它当做一个注册中心

从定位来讲,Eureka Server 确实只应该做注册中心该做的事,不应该关联到业务,尤其是服务多时,Eureka Server 维护压力大,更不应该关联业务

但有时候也需要特殊情况特殊处理,比如我目前的需求,注册中心维护的服务就一个 任务执行器,任务执行器的节点也不会很多,顶天 10 个,也就是 Eureka Servr 维护服务的压力会很小,同时业务处理也很简单:任务拆分,然后分发

这么分析下来,任务分发中心集成 Eureka Server 是可行的,说干就干!

干就完了
干就完了

Eureka server 搭建不要太简单,你们肯定都会

https://gitee.com/youzhibing/qsl-project/tree/master/integrate-eureka

搭建过程就不演示了,偷懒的小伙伴可以直接用我提供的代码

此时的代码结构如下(未包含业务代码)

代码结构
代码结构

搭建完成后启动服务,Eureka 监控如下

eureka搭建完成
eureka搭建完成

至此,Eureka 集成完成

你们发现没,前面的 Eureka 搭建跟我们平时的 Eureka 搭建是不是没区别?

肯定没区别呀,我就是按平时的搭建流程来的,具体区别还要往下看

分发中心集成 Eureka Client

为了更好的体现 任务分发中心 集成 Eureka Client,我们简化业务实现

任务执行器 就提供一个接口给 任务分发中心 调用

任务执行器接口_exec
任务执行器接口_exec

任务分发中心 也提供一个接口给其他服务(例如 调度中心)调用

分发中心接口
分发中心接口

重点来了,任务分发中心如何将拆分后的任务分发到任务执行器?

细化来讲,分 3 点 1.任务分发中心能不能拿到任务执行器服务列表 2.能拿到的话,如何拿 3.拿到之后如何负载均衡的下发任务

第 1 点毋庸置疑,肯定能拿到,任务分发中心作为 Eureka Server,存储了任务执行器的服务实例列表

第 2 、3点,我们可以将 任务分发中心 又当做 Eureka Client 试试,试试有不要钱

引入依赖 Eureka Server 包含了Eureka Client ,不需要额外引入Eureka Client 但需要引入 open-feign

代码语言:javascript
复制
<dependency>
	<groupId>org.springframework.cloud</groupId>
	<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

开启 Eureka Clientopen-feign

代码语言:javascript
复制
@SpringBootApplication
@EnableEurekaServer
@EnableEurekaClient
@EnableFeignClients
public class TaskDispatcherApplication {

    public static void main(String[] args) {
        SpringApplication.run(TaskDispatcherApplication.class, args);
    }
}

实现 TaskExecutorService,完成对 任务执行器 负载均衡调用

代码语言:javascript
复制
@FeignClient("TASK-EXECUTOR")
public interface TaskExecutorService {

    @GetMapping("task/exec")
    String exec(@RequestParam("taskId") Long taskId);
}
代码语言:javascript
复制
@GetMapping("dispatch")
public String dispatch(Long jobId) {
	LOGGER.info("收到作业[jobId={}]执行请求", jobId);
	LOGGER.info("作业[jobId={}]拆分任务中...", jobId);
	List<Long> taskIds = Arrays.asList(123L, 666L, 888L, 999L);
	LOGGER.info("作业[jobId={}]拆分完成,得到作业列表[{}]", jobId, taskIds);
	for (Long taskId : taskIds) {
		String execResult = taskExecutorService.exec(taskId);
		LOGGER.info("任务[{}]执行结果:{}", taskId, execResult);
	}
	return "success";
}

启动 task-dispatchertask-executor ,然后调用接口

http://192.168.2.10:8080/dispatcher/job/dispatch?jobId=689

你会发现 500

500
500

看下日志,关键信息如下

Load balancer does not contain an instance for the service TASK-EXECUTOR

负载均衡器不包含 TASK-EXECUTOR 服务实例,这是因为我们有个配置关闭了

fetch-registry-false
fetch-registry-false

导致 Eureka Client 未拉取其他服务,那么 Load balancer 自然就获取不到 TASK-EXECUTOR 实例了

我们将其开启(设置成 true),然后启动task-dispatchertask-executor,然后调用接口

http://192.168.2.10:8080/dispatcher/job/dispatch?jobId=689

结果 success,日志输出如下

task-dispatcher

代码语言:javascript
复制
2024-06-30 10:51:51.653|INFO|http-nio-8080-exec-3|25|com.qsl.task.web.JobController          :收到作业[jobId=689]执行请求
2024-06-30 10:51:51.653|INFO|http-nio-8080-exec-3|26|com.qsl.task.web.JobController          :作业[jobId=689]拆分任务中...
2024-06-30 10:51:51.653|INFO|http-nio-8080-exec-3|28|com.qsl.task.web.JobController          :作业[jobId=689]拆分完成,得到作业列表[[123, 666, 888, 999]]
2024-06-30 10:51:51.657|INFO|http-nio-8080-exec-3|31|com.qsl.task.web.JobController          :任务[123]执行结果:success
2024-06-30 10:51:51.660|INFO|http-nio-8080-exec-3|31|com.qsl.task.web.JobController          :任务[666]执行结果:success
2024-06-30 10:51:51.663|INFO|http-nio-8080-exec-3|31|com.qsl.task.web.JobController          :任务[888]执行结果:success
2024-06-30 10:51:51.665|INFO|http-nio-8080-exec-3|31|com.qsl.task.web.JobController          :任务[999]执行结果:success

task-executor

代码语言:javascript
复制
2024-06-30 10:51:51.656|INFO|http-nio-8081-exec-6|17|com.qsl.task.web.TaskController         :收到任务[taskId=123]执行请求
2024-06-30 10:51:51.656|INFO|http-nio-8081-exec-6|18|com.qsl.task.web.TaskController         :任务[taskId=123]执行中...
2024-06-30 10:51:51.656|INFO|http-nio-8081-exec-6|19|com.qsl.task.web.TaskController         :任务[taskId=123]执行完成
2024-06-30 10:51:51.659|INFO|http-nio-8081-exec-9|17|com.qsl.task.web.TaskController         :收到任务[taskId=666]执行请求
2024-06-30 10:51:51.659|INFO|http-nio-8081-exec-9|18|com.qsl.task.web.TaskController         :任务[taskId=666]执行中...
2024-06-30 10:51:51.659|INFO|http-nio-8081-exec-9|19|com.qsl.task.web.TaskController         :任务[taskId=666]执行完成
2024-06-30 10:51:51.662|INFO|http-nio-8081-exec-8|17|com.qsl.task.web.TaskController         :收到任务[taskId=888]执行请求
2024-06-30 10:51:51.662|INFO|http-nio-8081-exec-8|18|com.qsl.task.web.TaskController         :任务[taskId=888]执行中...
2024-06-30 10:51:51.662|INFO|http-nio-8081-exec-8|19|com.qsl.task.web.TaskController         :任务[taskId=888]执行完成
2024-06-30 10:51:51.664|INFO|http-nio-8081-exec-7|17|com.qsl.task.web.TaskController         :收到任务[taskId=999]执行请求
2024-06-30 10:51:51.664|INFO|http-nio-8081-exec-7|18|com.qsl.task.web.TaskController         :任务[taskId=999]执行中...
2024-06-30 10:51:51.664|INFO|http-nio-8081-exec-7|19|com.qsl.task.web.TaskController         :任务[taskId=999]执行完成

目前 task-executor 是单实例,我们再启动一个实例,来看看负载均衡效果

负载均衡
负载均衡

至此,需求是不是实现了

愣着干啥,鼓掌
愣着干啥,鼓掌

总结

  1. 注册中心推荐单独部署,不要掺杂业务代码
  2. Eureka Server 也可以做 Eureka Client,虽说不推荐,但有时候能止渴
  3. 要敢于尝试,不试怎么知道不行?
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-07-01,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 需求描述
  • 需求实现
    • 分发中心集成 Eureka Server
      • 分发中心集成 Eureka Client
      • 总结
      相关产品与服务
      负载均衡
      负载均衡(Cloud Load Balancer,CLB)提供安全快捷的四七层流量分发服务,访问流量经由 CLB 可以自动分配到多台后端服务器上,扩展系统的服务能力并消除单点故障。轻松应对大流量访问场景。 网关负载均衡(Gateway Load Balancer,GWLB)是运行在网络层的负载均衡。通过 GWLB 可以帮助客户部署、扩展和管理第三方虚拟设备,操作简单,安全性强。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档