想象一下,我有2套环境(蓝色和绿色)

           +
           |
           |
           |
           v
   +-------+---------+
   |     Proxy/LB    |
   |                 |
   +--+-------------++
      |             |
+-----++          +-+----+
|      |          |      |
|APP v1|          |APP v2|
|Blue  |          |Green |
+--+---+          +--+---+
   |                 |
+--+---+          +--+---+
| DB   |          | DB   |
| Blue | DB Sync  | Green|
|      <---------->      |
+------+          +------+



版本Blue当前正在运行,绿色已部署,并且所有数据库复制已完成。现在,我想将流量切换到绿色环境。在这种情况下,什么是管理数据库事务的最佳方法?(我在下面有一个想法)


将新流量转发给绿色,并等待现有蓝色环境的事务完成。完成所有操作后,将流量完全切换为绿色(更新:我可以使用Nginx做到这一点吗?)

如果上面的条件是正确的,那么我只需要做一些额外的工作就可以将新流量仅转发到绿色。

或者在这种情况下进行蓝绿色部署的最佳方法是什么?

PS:


我们正在使用Nginx proxy
所有服务器都是裸机,没有云!
2个独立的DB设置(带有主从关系的Postgresql)


评论

要仅路由新流量,您需要粘性cookie逻辑,只有nginx plus(付费)才支持。如果您正在寻找完全开源的解决方案,则可以在下面添加haproxy层。让我知道这是您要问的(如何将新的流量仅路由到新的部署)还是您的问题还有更多。如果这就是全部,请让我知道您是选择使用Nginx plus还是需要完全开源的解决方案,我可以详细说明。

@taleodor你可以回答。 Haproxy也会很棒。

#1 楼

根据Martin Flowers对蓝绿色部署的定义


蓝绿色部署方法通过确保您拥有两个尽可能相同的生产环境来做到这一点。在任何时候,其中一个(例如蓝色)都处于活动状态。准备新版本的软件时,您将在绿色环境中进行最后的测试阶段。一旦软件在绿色环境中运行,就可以切换路由器,以便所有传入的请求都进入绿色环境-蓝色的请求现在处于空闲状态。 br />您已经说过DB是使用master-slave拓扑进行同步的。
因此,要将流量从一个实例切换到另一个实例,我们必须采取以下步骤:


切换网站-从APP v1APP v2的流量

关机已弃用DB Blue

DB Green升级为master模式
DB Blue v2模式启动新的slave
(您可能会问-为什么?关闭DB Blue,而不是使用master-master复制或其他方式在DB Blue v1模式下将DB Greenmaster同步。请参阅DB replication中的说明)来自APP v1 APP v2-只需使用nginx reload-它会正常终止所有工作连接并将流量从App v1移动到App v2
对于使用shell / python脚本切换blue/green

例如:


meappy / docker-nginx-blue-green:使用ngx_http_perl_module的nginx的Docker蓝绿色上游>简单的0停机蓝绿色部署:Python简单的0停机蓝绿色部署示例/>
将样品green用于nginx / reload

http {

upstream appv1 {
    zone appv1 64K;
    server 10.10.0.1:80;
}

upstream appv2 {
    zone appv2 64K;
    server 10.10.0.3:80;
}

server {
...
location / {
    proxy_pass http://$appv1;
}
}

}


nginx替换nginx.conf

然后

>
nginx -s reload


停止reverse proxy


load balancer

proxy_pass http://$appv1;升级为proxy_pass http://$appvv;模式


使用在DB Blue中定义的触发器来触发促销


>
touch $PGDATA/failover



systemctl stop postgresql中删除DB Green触发


cd $PRIMARY_DATA
rm -f recovery.* failover  



确保master模式为在$PGDATA/recovery.conf模式下的failover上的Green DB

cat postgresql.conf | grep '#hot_standby = on'


数据库复制

备份主Green DB

psql -c "SELECT pg_start_backup('Streaming Replication', true)" postgresql://postgres@GreenDB/postgres


将备份发送到Blue DB

rsync -a $PG_DATA_Green_DB/ $BlueDB_IP:$PG_DATA_Blue_DB/ --exclude postmaster.pid --exclude postmaster.opts 


另请参阅


PostgreSQL中容错的演变

数据库迁移(更复杂但更健壮的数据库迁移方案)

您可以使用hot stanby和`Pglupgrade工具对迁移进行更复杂的方案:



有关详细信息,请参见:


云中PostgreSQL群集的近零宕机时间自动升级(第一部分)
近零宕机时间自动邮政升级Cloud中的greSQL群集(第二部分)

有一些定义。

...只是......


...排序间谍的买家,贪婪的人...


on vs Green DB vs master
定义,种类和测试类型

(请参阅这些答案中的详细信息)


蓝绿色部署-部署新版本的应用程序时,将创建第二个环境。测试新环境后,它将取代旧版本。然后可以关闭旧环境。
A / B测试-应用程序的两个版本同时运行。每个请求都有一部分请求。然后,开发人员可以比较版本。
金丝雀发布-微服务的新版本与旧版本一起启动。然后,该新版本可以接收部分请求,并且团队可以测试该新版本如何与整个系统交互。
功能标记-“配置”(冷或什至热)哪个功能(不)适用于哪个(组)用户的操作。如果您还进行“功能标记”之类的操作,则可以先进行部署,从向后兼容性/错误的角度衡量发布的合理性,然后逐步向不同用户发布新功能,反之亦然(按比例缩小甚至回滚功能和/或二进制文件) )。功能标记允许从部署二进制文件中分离功能的可用性,并提供比仅“部署/回滚”更细粒度的决策。
br /> source


蓝绿色和Canary发行版都实现了相同的目的
尽管这两个术语看起来非常接近,但它们之间存在细微的差异。一个对您的功能发布充满信心,另一个对您的发布方式充满信心。

蓝绿色部署


部署新版本的应用程序时,创建第二个环境。测试新环境后,它将取代旧版本。然后可以关闭旧环境。


Ansible

blue/green deployment

canary deployment

A/B test

Canary版本


微服务的新版本与旧版本一起启动。然后,该新版本可以接收部分请求,并且团队可以测试此新版本如何与整个系统交互。


Blue/Green

Canary

另请参见插图(源):

蓝色/绿色:

金丝雀:

评论


好答案!但是,A / B测试和Canaray版本的定义是相同的,这令人困惑。

– UserControl
20年4月2日在13:17

thx,添加了解释

–亚森
20年4月2日在19:19

这是我将要使用的常规方法,但它忽略了以下问题:“将新流量转发给绿色,并等待现有蓝色环境的交易完成。”相反,在这种Nginx开关下会发生什么-所有请求将立即转发为绿色,包括所有未完成的蓝色请求。

–taleodor
20-4-3在13:14

是的,您是对的-这是常规做法。至于这部分问题:“ ...并等待现有蓝色环境的事务完成”-nginx -s reload将正常切换流量。由于存在主从复制,因此无需将未完成的蓝色流量转发到绿色应用程序。我们只是让他们在蓝色节点上完成。

–亚森
20年4月3日,13:32

这个问题可以用更好的措辞来表达-所以我同意这还不是很清楚,这是什么意思,但是我最初是将其理解为多主方法。对于这种情况,我稍后会发布粘性cookie解决方案。如果是常规的主从同步,则大多数情况下您的解决方案都不错。

–taleodor
20-4-3在14:18



#2 楼

如所承诺的,这是使用haproxy和粘性cookie的解决方案。请注意,这种方法需要应用程序方面的支持(因为一旦完成事务,只有您的应用程序层才能知道)。

要实现这一点,首先-从以下类型的haproxy配置开始:

    global
        daemon
        maxconn 256
    defaults
        mode http
        timeout connect 5000ms
        timeout client 50000ms
        timeout server 50000ms

    frontend http-in
        bind *:80
        default_backend servers

    backend servers
        balance roundrobin
        cookie SID insert indirect preserve
        server server1 blue-server-hostname:8000 cookie sblue


请注意,此配置非常通用,摘自haproxy文档-来自此处:https://cbonte.github.io/haproxy-dconv/2.2/configuration.html #2.5

用于实现粘性的部分是最后添加的cookie指令,此处提供了详细文档:https://cbonte.github.io/haproxy-dconv/2.2/configuration。 html#4-cookie

因此,使用以下代码:

cookie SID insert indirect preserve


我们告诉haproxy插入名为SID的cookie,该cookie可能仅具有值sblue现在(此值在配置的最后一行中定义)。而且我们还说,如果该cookie由后端服务器提供,我们不希望haproxy覆盖它(通过insert和keep关键字实现)。

下一部分是添加一些应用程序级逻辑,将SID cookie设置为客户端,并使其值在应用程序端可配置。您想将SID cookie设置为旧代码为sblue,将新代码设置为sgreen。

现在,在进行部署时,起初只有蓝色实例,所有SID cookie都设置为sblue和haproxy将所有流量定向到唯一的蓝色实例。

下一步,添加绿色实例,然后在上面的配置末尾添加以下行,将其添加到haproxy: br />
server server2 green-server-hostname:8000 cookie sgreen


现在,对您的新绿色实例的任何请求都将其cookie设置为sgreen并坚持使用该新实例。

最后,您希望在旧的蓝色实例上进行应用程序级别的配置,以将cookie设置为在客户交易结束后对客户来说是绿色的(基本上是在应用程序知道这样做是安全的时候)。然后,来自此类客户端的任何新请求将被定向到绿色实例。在某个时候,您所有的请求都将转换为绿色-并且您可以在那时分离蓝色实例。层事务逻辑。