欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

uWSGI订阅服务器

程序员文章站 2022-06-06 19:06:05
...

uWSGI栈的一些组建需要一个键值映射系统。

比如,The uWSGI FastRouter需要知道某个请求要发到哪个服务器上。

在一个具有很多节点的网络中,手工维护这个配置会是地狱一般的体验。uWSGI实现了一个订阅系统,节点可以利用这个订阅系统向订阅服务器声明其存在,这样就会反过来填充订阅服务器的内部字典。

uwsgi --fastrouter :1717 --fastrouter-subscription-server 192.168.0.100:2626

这会在1717端口上运行一个uWSGI fastrouter,并创建一个空的字典,其中键为主机名,值为uwsgi地址。

可以通过联系192.168.0.100:2626这个订阅服务器地址来填充这个字典。

对于每个键,可以对应存在多个地址,这样就可以开启负载均衡(可以使用多种负载均衡算法)。

几点可以通过使用subscribe-to或者subscribe2选项来向订阅服务器声明其存在。

uwsgi --socket 192.168.0.10:3031 --wsgi myapp -M --subscribe-to 192.168.0.100:2626:uwsgi.it

FastRouter会将对uwsgi.it的每个请求映射到192.168.0.31:3031上。

现在为uwsgi.it添加第二个节点,再次运行并订阅即可:

uwsgi --socket 192.168.0.11:3031 --wsgi myapp --master --subscribe-to 192.168.0.100:2626:uwsgi.it

死亡节点会被自动从这池中移除掉。

subscribe2的语法与之类似,只是其可以允许更多的控制,比如可以指定所有请求都应该被转发到的地址。它的值的语法是一个“键-值”对的字符串,通过逗号来区分分割不同的键值对。

uwsgi -s 192.168.0.10:3031 --wsgi myapp --master --subscribe2 server=192.168.0.100:2626,key=uwsgi.it,addr=192.168.0.10:3031

可用的subscribe2键列表,可以参考下面的内容。

订阅系统当前可用于加入集群(当多播/广播不可用时),Fastrouter、HTTP/HTTPS/SPDY路由,rawrouter和sslrouter。

也就是说你可以立即创建一个事件驱动的/性能极好的HTTP负载均衡器。

uwsgi --http :80 --http-subscription-server 192.168.0.100:2626 --master

现在只需要简单地将你的节点订阅到HTTP订阅服务器即可。

可以通过http-stats-server选项来检查订阅服务器的统计信息和/或参与订阅的节点。

uwsgi --http :80 --http-subscription-server 192.168.0.100:2626 --http-stats-server 192.168.0.100:5004 --master

可以使用http-resubscribe选项将订阅请求转发到其它服务器。

uwsgi --http :80 --http-subscription-server 192.168.0.100:2626 --http-resubscribe 192.168.0.101:2627 --master

订阅系统安全

这个订阅系统适用于“受信任”网络。网络中的所有节点都可能让整个网络变得一团糟。

如果你正在为不受信任的用户构建一个架构,或者你仅仅是需要控制谁能够去订阅订阅服务器,你就可以使用openssl rsa公钥/私钥对用来“签名”订阅请求。

# 首先,为订阅者创建一个私钥。不要为这个私钥设置口令
openssl genras --output private.pem
# 为订阅服务器创建公钥:
openssl rsa -pubout -out test.uwsgi.it_8000.pem -in private.pem

公钥必须被命名为我们要订阅提供服务器的域以及.pem扩展名命名。

注意

如果你是在为一个监听于特定端口的应用订阅,你需要使用domain_port.pem的结构来命名公钥文件。通常所有DNS允许的字符都是可以使用的,其它字符被映射为下划线。

一个由RSA保护的服务器的例子,是这个样子的:

[uwsgi]
master = 1
http = :8000
http-subscription-server = 127.0.0.1:2626
subscriptions-sign-check = SHA1:/etc/uwsgi/keys

最后一行告诉uWSGI,公钥文件存储于/etc/uwsgi/keys中。

对于每次订阅请求,服务器会去检查对应的公钥的可用性,如果有,就使用它来验证包的签名。未能通过验证的包会被拒绝。

在客户端,你需要将私钥在subscribe-to选项中进行指定。下面是一个例子:

[uwsgi]
socket = 127.0.0.1:8080
subscribe-to = 127.0.0.1:2626:test.uwsgi.it:8000,5,SHA1:/home/foobar/private.pem
psgi = test.psgi

我们来分析一下subscribe-to的使用:

  • 127.0.0.1:2626是我们想要去订阅的订阅服务器。
  • test.uwsgi.it:8000是订阅键。
  • 5是psgi应用的modifer1的值
  • SHA1:/home/foobar/private.pem是<digest>:<rsa>对,用于服务器认证(其中<rsa>是私钥路径)

注意

请确定在服务器和客户端上使用相同的摘要方法(在上面的例子中是SHA1)。

为了避免重放攻击,每个订阅包都有一个自增数字(通常就是unix时间),用于禁止重复的包。即使是一个攻击者能够嗅探到一个订阅包,也是没有任何用处的,因为这个包之前已经处理过了。显然,如果有人拿到了你的私钥,他就能够构建伪造的包了。

使用SSH**

SSH格式的**受到开发者的普遍欢迎(当然,是相比于经典的PEM文件)。

-subscribe-to和-subscribe2(见下文)都支持SSH私钥,而对于服务器部分,你需要将公钥编码为pkcs8格式:

ssh-****** -f chiavessh001.pub -e -m pkcs8

-subscribe2

这是-subscribe-to的键值对版本。它支持更多的配置,并有一个(通常)更可读的语法:

uwsgi --socket 127.*:0 --subscribe2 server=127.0.0.1:7171,key=ubuntu64.local:9090,sign=SHA1:chiavessh001

支持的字段有:

  • server 订阅服务器的地址
  • key 订阅的键(通常是域名)
  • addr 要订阅的地址(此项的值)
  • socket 套接字编号(从零开始),这类似于‘addr’,只是取内部套接字的编号
  • weight 负载均衡值
  • modifier1和modifier2
  • sign <algo>:<file>安全系统的签名
  • check 接收一个文件。如果其存在就发送包,否则就跳过
  • sni_key 为SNI代理管理设置key file
  • sni_crt 为SNI代理管理设置crt file
  • sni_ca 为SNI代理管理设置 ca file
  • algo (uWSGI 2.1)设置使用的负载均衡算法(可插拔,包括wrr,lrc,wlrc和iphash)
  • proto(uWSGI 2.1)使用的协议,默认是‘uwsgi’
  • backup(uWSGI 2.1)设置备份等级(根据不同的算法,意义有所变化)

通知

当你订阅到一个服务器的时候,你可以要求它“确认”对请求的接受。

只需要加上--subscription-notify-socket <addr>指向一个数据报(Unix或者UDP)地址,你的一个服务实例会绑定到这个地址上,订阅服务器会发送确认到这个服务器。

挂载点(uWSGI 2.1)

通常你会将应用订阅到某个域名上。

由于有了uWSGI 2.1中引入的挂载点支持,你可以订阅每个节点到一个特定的目录上(你需要指定想要支持多少层):

首先,你需要告知订阅服务器接受(并处理)挂载点请求:

uwsgi --master --http :8080 --http-subscription-server 127.0.0.1:4040 --subscription-mountpoints 1

让后你就可以订阅到挂载点上了。

uwsgi --socket 127.0.0.1:0 --subscribe2 server=127.0.0.1:4040,key=mydomain.it/foo
uwsgi --socket 127.0.0.1:0 --subscribe2 server=127.0.0.1:4040,key=mydomain.it/bar
uwsgi --socket 127.0.0.1:0 --subscribe2 server=127.0.0.1:4040,key=mydomain.it/foo
uwsgi --socket 127.0.0.1:0 --subscribe2 server=127.0.0.1:4040,key=mydomain.it

第一个和第三个实例会回应对/foo的请求,第二个会回应对/bar的请求,最后一个会处理剩余其它的请求。

对于安全的订阅系统,你只需要使用域名**(不要为每个挂载点生成一个证书)。

如果你想要支持类似于/one/two,而不是/one形式的挂载点,只需要对--subscription-mountpoints选项指定‘2’即可。出于性能考量,你需要选择路径可支持的元素的数量,并且不能混用(就是说:如果-subscription-mountpoints为2,你可以支持/one/two或者/foo/bar,但是不能支持/foobar)。

相关标签: WSGI