内容纲要
背景
最近做的一个需求要对接 google play 和 paypal,我负责的是 paypal 部分,google play 另一个同事对接。
paypal 的访问比较慢,超时时间 5 秒才勉强够用,同事那边对接 google play 就更麻烦,因为墙的缘故,google play 的接口根本无法访问。
解决办法是在香港部署一个服务器,在香港服务器上起一个基于 gRPC 的微服务,国内服务器通过调用香港的微服务来实现 google play 的访问。
跟同事沟通后,感觉这样还是比较麻烦的,微服务的部署并不是简单的部署一个进程,还需要一系列的配套设施,比如服务注册,以我们的架构就需要一个 discovery,由于香港这边的服务器仅仅起到一个服务转发的作用,所以是专门做的一个微服务,并不运行任何业务逻辑,国内的服务器也是写死了服务地址来访问香港这边的微服务的。
这个微服务的代码还需要维护,比如说以后接入其他合作方,就需要增加新的接口
使用 nginx 代理
当时我就觉得,这样的需求完全没有必要搞个微服务。理论上用 nginx 代理一下完全可行,于是我抽出时间做了个实验,验证了一下想法
延时比较
我的实验很简单,通过香港服务器上安装 nginx 来代理我对 paypal 的访问,我的访问地址是
https://api-m.sandbox.paypal.com/v1/oauth2/token
先看下我到 api-m.sandbox.paypal.com
的延时
ping api-m.sandbox.paypal.com
正在 Ping e7009.a1.akamaiedge.net [96.16.191.238] 具有 32 字节的数据:
来自 96.16.191.238 的回复: 字节=32 时间=228ms TTL=56
来自 96.16.191.238 的回复: 字节=32 时间=228ms TTL=56
来自 96.16.191.238 的回复: 字节=32 时间=228ms TTL=56
来自 96.16.191.238 的回复: 字节=32 时间=228ms TTL=56
然后在香港服务器上 ping 一下
ping api-m.sandbox.paypal.com
PING e7009.a1.akamaiedge.net (184.28.35.99) 56(84) bytes of data.
64 bytes from a184-28-35-99.deploy.static.akamaitechnologies.com (184.28.35.99): icmp_seq=1 ttl=58 time=1.97 ms
64 bytes from a184-28-35-99.deploy.static.akamaitechnologies.com (184.28.35.99): icmp_seq=2 ttl=58 time=1.95 ms
64 bytes from a184-28-35-99.deploy.static.akamaitechnologies.com (184.28.35.99): icmp_seq=3 ttl=58 time=1.94 ms
64 bytes from a184-28-35-99.deploy.static.akamaitechnologies.com (184.28.35.99): icmp_seq=4 ttl=58 time=1.94 ms
可以发现从香港访问延时低太多了,那么我到香港服务器的延时又是多少呢?
ping hk.refusea.com
正在 Ping hk.refusea.com [***.***.***.***] 具有 32 字节的数据:
来自 **.**.**.** 的回复: 字节=32 时间=16ms TTL=49
来自 **.**.**.** 的回复: 字节=32 时间=17ms TTL=49
来自 **.**.**.** 的回复: 字节=32 时间=26ms TTL=49
结论
- 我在国内直接访问 paypal,延时 200 多 ms
- 我访问香港服务器,延时 20 ms
- 香港服务器访问 paypal,延时 2 ms
通过香港服务器中转,可以极大的提升响应时间
代理配置
直接贴出代码吧
server {
listen 80;
server_name hk.refusea.com;
access_log /data/logs/nginx/hk_access.log main;
proxy_store off;
proxy_redirect off;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_http_version 1.1;
proxy_set_header X-Real-IP $remote_addr;
# 转发到沙盒环境
location /paypal-sandbox/ {
# proxy_set_header Host "api-m.sandbox.paypal.com";
proxy_pass https://api-m.sandbox.paypal.com/;
}
# 转发到生产环境
location /paypal/ {
proxy_pass https://api-m.paypal.com/;
}
}
说明
- 可以用 http 代理 https 网站
- 可以用一个域名代理多个域名
- 无需在配置里设置域名
- 最初没有设置
proxy_
开头的几个属性时,转发不成功,设置以后就 ok 了 - 在我的代码里,访问 paypal 的地址分别为
结论
虽然没有用 google 的接口进行实验,但我相信 nginx 代理是完全可行的,即便是国内可以访问的网站,用 nginx 代理来加速也是完全 ok 的
nginx 反向代理外部网站
server {
server_name sqs-eu-west-1-amazonaws.xx.com;
listen 443 ssl;
ssl_certificate /data/nginx/cert/xx.com.pem;
ssl_certificate_key /data/nginx/cert/xx.com.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
location / {
proxy_pass https://sqs.eu-west-1.amazonaws.com;
proxy_connect_timeout 30;
proxy_send_timeout 600;
proxy_read_timeout 600;
proxy_set_header Host $host:$server_port;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_store off;
proxy_redirect off;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_http_version 1.1;
}
}
X-Forwarded-For: 192.168.72.180
bodyBytesSent: 1219
httpHost: xx.com
httpReferer:
httpUserAgent: aws-sdk-java/1.11.943 Linux/4.19.91-26.6.al7.x86_64 OpenJDK_64-Bit_Server_VM/25.292-b10 java/1.8.0_292 groovy/3.0.9 vendor/Oracle_Corporation
origin:
remoteAddr: 192.168.72.180
remoteUser:
request: POST /933233001598/ADS_AMS_X_EU_SZ_PROD/ HTTP/1.1
requestLength: 885
requestTime: 0.873
status: 403
timeLocal: 2024-01-09T17:57:45+08:00
upstreamResponseTime: 0.873
upstream_addr: 3.250.244.19:443
你的配置不对,server 应该是你自己的服务器,而不是 amazon 的服务器
另外,不要试图用这种模式来代理一个网页,因为网页很可能还要加载图片,css,js,甚至 ajax,这些域名往往不一样,除非你全部配置代理,这种情况直击用 shadowsocks 吧