一、问题描述
在实际工作中,一个商品微服务下面可能挂着多个商品服务器,每个商品服务器里的商品服务代码是相同的。
但是这样一来,如果进行服务注册,那就意味着每一个商品服务器注册的都是同一个ip和端口号,因为代码是完全一致的。
这个问题在git、svn中都会存在。
二、解决思路
1、在.env文件中手动添加两个常量【不推荐】
在非共享目录手动创建.env文件,在里面创建一个标识IP和端口号的两个常量。
该方式的缺点在于没有实现自动化,如果水平扩容,还得每台服务器挨个修改.env
2、获取主机IP,然后把ip写入.env【推荐】
第二种方式是通过某种方式,获取到主机的ip,再把该ip写入.env,然后让swoft加载该.env文件
该方式的优点是实现了自动化,即使水平扩容,也不必再去挨个服务器的修改.env
三、解决方案
这里第一种解决方案不必多说,只说第二种方案如何实现。
1、获取到服务器IP值
# 执行命令即可获取
ifconfig | grep 172.22 | awk '{print $2}'
root@00f304bcbc83:/# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.22.22.110 netmask 255.255.255.0 broadcast 0.0.0.0
inet6 fe80::42:acff:fe16:166e prefixlen 64 scopeid 0x20<link>
ether 02:42:ac:16:16:6e txqueuelen 0 (Ethernet)
RX packets 4136 bytes 724809 (707.8 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 62 bytes 6333 (6.1 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1000 (Local Loopback)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
root@00f304bcbc83:/# ifconfig | grep 172.22 | awk '{print $2}'
172.22.22.110
2、编写一个sh脚本,定时将获取到的值写入.env
docker exec -it swoft_110 bash
cd /var/www/swoft/
vi generate_ip.sh
#! /bin/sh
host=`ifconfig | grep 172.22 | awk '{print $2}'`
content="HOST="$host
echo $content >> /var/www/.env
因为我们设置了三个swoft的代码都在/var/www/swoft下,所以我们为了避免每一个swoft下的ip一样,应该把.env放在上一层目录。
当然,在生产环境不用如此,因为生产环境是通过同步代码的方式保证业务代码的相同,但.env不在同步代码的范畴内,所以在生产环境中不用将.env放到其他目录,直接放到根目录即可。
注:一个>时,内容是会覆盖原文件的,而两个>时,内容会在原文件内容基础上进行追加,这里采用的是追加
3、执行该脚本,在该容器内生成一个.env
cd /var/www/swoft/
sh ./generate_ip.sh
注:该操作在其他两个swoft容器内也要执行
4、让swoft加载该.env
修改bin/swoft文件,将(new \App\Application())->run();
修改为
$app = new \App\Application();
$app->setEnvFile('/var/www/.env');
$app->run();
5、验证是否加载成功
在app/Listener/RegisterServiceListener.php文件中的handle方法中添加一行代码:
echo env('HOST').PHP_EOL;
然后执行 ./bin/swoft rpc:start
启动rpc服务,正常应该有输出IP地址,说明成功。
____ _____ ____ __ ___ ___
/ __/ _____ / _/ /_ / __/______ ___ _ ___ _ _____ ____/ /__ |_ | / _ \
_\ \| |/|/ / _ \/ _/ __/ / _// __/ _ `/ ' \/ -_) |/|/ / _ \/ __/ '_/ / __/_/ // /
/___/|__,__/\___/_/ \__/ /_/ /_/ \_,_/_/_/_/\__/|__,__/\___/_/ /_/\_\ /____(_)___/
SERVER INFORMATION(v2.0.10)
**************************************************************
* RPC | Listen: 0.0.0.0:18308, Mode: Process, Worker: 2
**************************************************************
RPC Server Start Success!
2021/09/09-19:41:35 [INFO] Swoft\Server\Server:startSwoole(499) Swoole\Runtime::enableCoroutine
2021/09/09-19:41:35 [INFO] Swoft\Listener\BeforeStartListener:handle(35) Server extra info: pidFile @runtime/swoft-rpc.pid
2021/09/09-19:41:35 [INFO] Swoft\Listener\BeforeStartListener:handle(36) Registered swoole events:
start, shutdown, managerStart, managerStop, workerStart, workerStop, workerError, connect, close, receive
哈哈哈Swoft rpc register service success by consul哈哈哈!
172.22.22.110
Server start success (Master PID: 200, Manager PID: 207)
可以看到,已经成功输出了172.22.22.110,说明我们加载.env文件成功了。
6、温馨提示
不要忘记把我们临时校验的代码删除了哦( ̄3 ̄)a
# app/Listener/RegisterServiceListener.php中的handle方法
echo env('HOST').PHP_EOL;