介绍

人们喜欢谈论微服务。"你应该迁移到微服务",他们说。但是,为什么呢?当开始做产品时,你会被催促着建立更多的功能。通常情况下,它将增长到你的员工的2x-3x的数量。目前,流量还没有那么大。你得到的少数客户应该被视为天使投资人。因为你需要确保你的应用程序的工作,尽管在几个功能上有很多变化。

解决方案

你需要将你的应用程序分割成多个服务,分别升级或添加服务。当升级失败时,它可以被回滚,所以它将更安全。但是,它很难管理许多服务。你需要docker或kubernetes。然后使用管理平台,如portainer、docker swarm或rancher。还有,不要忘记安装api网关、grpc和graphql。为了提供数据的一致性,请使用消息代理将你的后端折射为事件驱动的架构。对于升级版本,你可以使用特性标志,或者使用gitlab CI进行CI/CD。但是,最近用gitlab CI实现的CI/CD是错误的。最好只用gitlab CI做CI,而用terraform做CD。所以,你需要用terraform(和ansible)把你的架构重写成云架构。它仍然需要写集成测试和模拟服务器,以确保CI在staging上正常运行。不要忘记使用fluentd、loki等进行监控,这样你就可以通过追踪x-request-id来跟踪微服务中的用户行为。

用Openresty部署Canary

金丝雀大多谈论A/B测试。但是,A/B测试通常有一些目标计划。在这种情况下,使用百分比进行分割是很奇怪的。当你把金丝雀分成10%的时候,一个人用两个设备会得到不同的版本。

在这个小型创业公司中,金丝雀被用来根据哪些普通用户和VIP用户来分割流量。VIP用户由他们支付的费用或其他有影响的方面决定,或者你的应用程序对他们的业务有多大影响(长期用户)。

在这个例子中,我们通过以下步骤将流量按http cookie分开。

  1. 后台对任何想被标记的用户会话设置cookie ISCANARY=true。
  2. lua脚本读取http cookie。
  3. lua脚本从redis读取所有的上游。
  4. 改变nginx配置的lua脚本上游
*操作系统: Centos 7*

pip安装Flask

vim main.py

import sys from flask import Flask port = 10000 message = "default message" try: port = int(sys.argv[1]) message = str(sys.argv[2]) except Exception as e: pass app = Flask(__name__) @app.route("/", methods=["GET"]) def getMessage(): return message "\n"if __name__=='__main__': app.run(debug=True,port=port)

python main.py 10001 "This is version 1" python main.py 10002 "This is version 2" []# curl localhost:10001 This is version 1 []# curl localhost:10002 This is version 2

先决条件。

wget https://openresty.org/package/centos/openresty.repo mv openresty.repo /etc/yum.repos.d/ yum -y install openresty openresty-resty systemctl enable openresty systemctl start openresty ln -s /usr/local/openresty/nginx/conf /etc/nginx ln -s /usr/local/openresty/nginx/logs /var/log/nginx mkdir /etc/nginx/conf.d export PATH=/usr/local/openresty/nginx/sbin:$PATH

vim /etc/bashrc

... ... export PATH=/usr/local/openresty/nginx/sbin:$PATH

vim /etc/nginx/nginx.conf

http { ... include /etc/nginx/conf.d/*.conf; }

vim /etc/nginx/conf.d/canary.conf

#map $http_upgrade $connection_upgrade{ # default upgrade; # `` close; #} upstream v1{ server 127.0.0.1:10001; } upstream v2{ server 127.0.0.1:10002; } server { listen 80 ; server_name tools2online.com; location / { proxy_pass http://v1; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; #proxy_set_header Upgrade $http_upgrade; #proxy_set_header Connection "Upgrade"; proxy_http_version 1.1; } }

nginx -t

nginx -s reload

[]# curl http://tools2online.com This is version 1

Lua脚本写起来有点不寻常。我们将尝试一步一步地实现lua。

  1. Nginx配置

openresty 高并发配置(NGINX为小型应用程序进行简单的金丝雀部署)(1)

  1. 通过lua块配置 *似乎proxy_pass被lua块覆盖了

openresty 高并发配置(NGINX为小型应用程序进行简单的金丝雀部署)(2)

  1. 在lua块中创建函数 *it import script from hello.lua on dir $prefix/conf/lua/.

openresty 高并发配置(NGINX为小型应用程序进行简单的金丝雀部署)(3)

  1. 在lua文件中创建函数 *lua块可以被写成文件

openresty 高并发配置(NGINX为小型应用程序进行简单的金丝雀部署)(4)

  1. 测试随机数

openresty 高并发配置(NGINX为小型应用程序进行简单的金丝雀部署)(5)

  1. 设置上游 *有可能以随机方式分割流量。不建议这样做,因为它可能会导致不一致的http响应。 1.websocket 2.资产 3.同一个用户,两个浏览器标签,显示不同的版本。

openresty 高并发配置(NGINX为小型应用程序进行简单的金丝雀部署)(6)

  1. 基于http cookie的上游路由 *金丝雀的最安全策略是使用cookie(仅限http),它可以从后台控制某些用户是否会在金丝雀组中。

openresty 高并发配置(NGINX为小型应用程序进行简单的金丝雀部署)(7)

  1. Lua从redis中读取json *在上一个例子中,上游是硬编码的配置。它有可能从redis上进行二进制配置。

openresty 高并发配置(NGINX为小型应用程序进行简单的金丝雀部署)(8)

总结

在这篇文章中,我们证明了在特定情况下使用canary和openresty是可行的,比如保护你的VIP用户不受部署后错误的影响。有些人建议用Nginx Proxy Manager代替openresty,以方便配置管理。也许这可以改进为两个不同的路径。首先,从NginxPM更新redis。第二,将数据从redis迁移到NginxPM数据库。但它应该比redis慢很多。

,