3

本地同时启停多个中间件的优雅方案 - 程语有云

 1 year ago
source link: https://www.cnblogs.com/mylibs/p/local-fake-docker.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

"I don’t care if it works on your machine! We are not shipping your machine!" - Vidiu Platon

“我才不管它能不能在你的机器上运行捏!我们又不会给你提供机器!” —— 韦都·柏拉图

0x00 大纲#

0x01 前言#

随着微服务架构风格的推广应用,开发人员的本地开发和调试成本大大提高,甚至不堪重负。动不动就要依赖一揽子东西,注册中心、Redis、MQ、基础服务ABC……等等。

开发人员如果手工在本地启停多个基础服务和中间件,将会浪费大量时间,降低开发效率。

0x02 大公司的解决方案#

DockerKubernetes,不缺钱也不缺人的首选。什么双活、负载均衡统统来个四五套,把寒气也传给运维人员。

0x03 小作坊的解决方案#

为了节约成本,当然是要在本地启动一整套系统节点啦,毕竟内存成本比人力成本低得多。但是手工启停太浪费时间了,这样会导致本来就不多的摸鱼时间所剩无几。人生苦短,我用脚本。

确定了方案,我就开始着手编排了,以一个Zookeeper + Redis(一主二从三哨兵)的启停脚本为目标,配置过程就略过了,着重解决启停的问题。

试作一号#

启动脚本#

@echo off
color 5f
title fake-docker
echo ^>^>^>^>^>^>^>^>bootstrapping redis...
start "redis-master" "c:\dev\redis-x64-3.2.100\redis-server.exe" "c:/dev/redis-x64-3.2.100/redis.master-1.conf"
start "redis-slaver-1" "c:\dev\redis-x64-3.2.100\redis-server.exe" "c:/dev/redis-x64-3.2.100/redis.slaver-1.conf"
start "redis-slaver-2" "c:\dev\redis-x64-3.2.100\redis-server.exe" "c:/dev/redis-x64-3.2.100/redis.slaver-2.conf"
start "redis-sentinel-1" "c:\dev\redis-x64-3.2.100\redis-server.exe" "c:/dev/redis-x64-3.2.100/redis.sentinel-1.conf" --sentinel
start "redis-sentinel-2" "c:\dev\redis-x64-3.2.100\redis-server.exe" "c:/dev/redis-x64-3.2.100/redis.sentinel-2.conf" --sentinel
start "redis-sentinel-3" "c:\dev\redis-x64-3.2.100\redis-server.exe" "c:/dev/redis-x64-3.2.100/redis.sentinel-3.conf" --sentinel
echo ^>^>^>^>^>^>^>^>done!
echo ^>^>^>^>^>^>^>^>bootstrapping zookeeper...
start "zookeeper-dev" "c:\dev\apache-zookeeper-3.6.3-bin\bin\zkServer.cmd"
echo ^>^>^>^>^>^>^>^>system is hot!

停止脚本#

@echo off
color 5f
echo ^>^>^>^>^>^>^>^>shutdowning...
taskkill /t /f /fi "imagename eq redis-server.exe" >nul
taskkill /t /f /fi "windowtitle eq zookeeper-dev" >nul
echo ^>^>^>^>^>^>^>^>system is down!
pause>nul

第一个版本,解决了启动和停止的问题,但是是手动档的,重启中间件的话要执行两个脚本。待改进的问题有两个:

  • 重启不方便,尽量做到一键启停
  • 弹出窗口太多,体验不佳

第一个问题容易解决,先停后起,先执行停止指令,再把应用拉起来。

第二个问题有点麻烦,一开始想尝试无窗口启动,反复尝试未果,后来采用了折中方案,在CMDstart命令帮助中有如下描述:

C:\Users\Master>help start

启动一个单独的窗口以运行指定的程序或命令。

START ["title"] [/D path] [/I] [/MIN] [/MAX] [/SEPARATE | /SHARED]
[/LOW | /NORMAL | /HIGH | /REALTIME | /ABOVENORMAL | /BELOWNORMAL]
[/NODE ] [/AFFINITY ] [/WAIT] [/B]
[command/program] [parameters]

"title"     在窗口标题栏中显示的标题。
path        启动目录。
B           启动应用程序,但不创建新窗口。
            应用程序已忽略 ^C 处理。除非应用程序
            启用 ^C 处理,否则 ^Break 是唯一可以中断
            该应用程序的方式。
I           新的环境将是传递
            给 cmd.exe 的原始环境,而不是当前环境。
MIN         以最小化方式启动窗口。
MAX         以最大化方式启动窗口。
SEPARATE    在单独的内存空间中启动 16 位 Windows 程序。
SHARED      在共享内存空间中启动 16 位 Windows 程序。
LOW         在 IDLE 优先级类中启动应用程序。
NORMAL      在 NORMAL 优先级类中启动应用程序。
HIGH        在 HIGH 优先级类中启动应用程序。
REALTIME    在 REALTIME 优先级类中启动应用程序。
ABOVENORMAL 在 ABOVENORMAL 优先级类中启动应用程序。
BELOWNORMAL 在 BELOWNORMAL 优先级类中启动应用程序。
NODE        将首选非一致性内存结构(NUMA)节点指定为
            十进制整数。
AFFINITY    将处理器关联掩码指定为十六进制数字。

根据描述,如果start时带上/b参数,就能让多个程序在一个窗口中寄宿。修改后得到最终版本:

最终版本#

@echo off
color 5f
title %date%
echo ^>^>^>^>^>^>^>^>cleaning up context...
echo ^>^>^>^>^>^>^>^>killing previous runner...
taskkill /t /f /fi "imagename eq redis-server.exe" >nul
taskkill /t /f /fi "windowtitle eq fake-docker*" >nul
timeout /t 3 /nobreak >nul
rd /s /q "c:\tmp\zookeeper">nul
echo ^>^>^>^>^>^>^>^>clean up context done!
title fake-docker
echo ^>^>^>^>^>^>^>^>bootstrapping redis...
start /b "redis-master" "c:\dev\redis-x64-3.2.100\redis-server.exe" "c:/dev/redis-x64-3.2.100/redis.master-1.conf"
start /b "redis-slaver-1" "c:\dev\redis-x64-3.2.100\redis-server.exe" "c:/dev/redis-x64-3.2.100/redis.slaver-1.conf"
start /b "redis-slaver-2" "c:\dev\redis-x64-3.2.100\redis-server.exe" "c:/dev/redis-x64-3.2.100/redis.slaver-2.conf"
start /b "redis-sentinel-1" "c:\dev\redis-x64-3.2.100\redis-server.exe" "c:/dev/redis-x64-3.2.100/redis.sentinel-1.conf" --sentinel
start /b "redis-sentinel-2" "c:\dev\redis-x64-3.2.100\redis-server.exe" "c:/dev/redis-x64-3.2.100/redis.sentinel-2.conf" --sentinel
start /b "redis-sentinel-3" "c:\dev\redis-x64-3.2.100\redis-server.exe" "c:/dev/redis-x64-3.2.100/redis.sentinel-3.conf" --sentinel
echo ^>^>^>^>^>^>^>^>done!
echo ^>^>^>^>^>^>^>^>bootstrapping zookeeper...
start /b "zookeeper-dev" "c:\dev\apache-zookeeper-3.6.3-bin\bin\zkServer.cmd"
echo ^>^>^>^>^>^>^>^>system is hot!

最终版本,实现了一键启停,只会产生一个命令行窗口,属于能用的范畴了。在此基础上,可以根据项目情况,自行添加其他中间件或基础服务的启停命令。

0x04 小结#

分布式应用调试和部署不可避免会面临几个问题:

应用启停困难#

通常由于架构的原因,为了调试某个中间节点或上游应用的功能,需要把相关的应用都启动起来,如果手工启停,无疑是痛苦的。

外部系统不稳定#

如果不能把整个系统都在本地启动起来,那么本地就会有一部分服务依赖于外部公共环境,它们通常不止一个人甚至不止一个团队在用。 一旦外部服务不可用,就会影响到本地的开发和测试。

因此准备一个微型本地开发环境是有必要的,至少在开发和调试阶段。况且如果最困难的启停问题被解决了,何乐不为呢?


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK