客户端灰度发布,NGINX+GeoIP2+GeoIP Database

需求的产生 (分地区更新)

我们公司呢是做电商平台的,其主打商品里有一款智能饮水机产品,而每台智能饮水机产品都是装在全国客户的家里。为了售后维护需要服务端如何保存数据并传回这块实现较简单,而在远程展示水机的余额、归属地、出水的质量等功能这块是由水机自身所镶嵌的一块智能PAD屏所完成,其PAD内部安装的是安卓系统;
在由开发完成新功能的开发后需迭代智能PAD屏内部安卓系统APK版本时,在更新版本这块我们一直做的方法是全量更新不做任何更新上的限制。但随着业务量的增加全国大概有30万台水机版本需要更新,显然之前的更新方式不再适用于现有这种高业务量的需求了。所以我们考虑了一个新的更新方案 "按地区更新";

参考的方案

一、最直接的方案是购买阿里云的CDN,利用CDN的缓存来实现。缓存原理如下

  • 通过CDN访问的流程是:客户端-->CDN L1--->CDN L2--->源站;
  • 客户端请求到的CDN节点是CDN的L1节点,当客户端请求到CDN的L1节点向该节点请求一个资源的时候,该CDN节点会查询本节点是否有这个资源,如有这个资源就会直接返回给客户端。如果没有这个资源,CDN L1节点就会向CDN的L2节点去请求资源,L2节点如果有缓存该文件,那么L1向L2拿到数据以后就返回给客户端。如果L2节点也没有缓存该资源,那么CDN的L2节点会回源向源站去请求这个资源然后返回给客户端,并且根据具体的缓存规则把该资源缓存下来,具体缓存多久是根据缓存规则而定一旦缓存过期CDN节点就会清空该资源,等到下一次有客户端请求到该节点的时候,CDN才会回源去获取数据。这里一个L2节点是对应多个L1节点的,如果L1没有命中缓存,L2命中了缓存,那么最终也是命中缓存的;
  • 如果源站更新了APK文件,而CDN缓存还没有过期的话,客户可能会请求到老的APK数据。所以源站更新数据以后,需要到CDN上去刷新下缓存;
  • 后来考虑项目成本的问题就放弃了;

二、采用灰度发布

  • 由于各项目的不互通性,而且灰度发布是在代码层实现的,不好应用到现在这个架构中;
  • 这种灰度的方式是根据版本号来迭代,即前端+CDN+Nginx的方式;
  • 讨论过以后开发周期长,维护人员成本较高
  • 后来思路还是放在Nginx上,Nginx+GeoIP Modules+GeoIP Datebase;
  • 一点想法都没有,该花的钱还是要花啊啊啊;

Nginx+GeoIP Modules+GeoIP Datebase

  • 编译Nginx引入第三方模块,这里注意了需引入之前已编译成功后的第三方模块,不然你就完了...
  • 下载GeoIP库 传送门 ,解压到/usr/share/GeoIP目录下。此类资源在网内csdn还是有的比较有心;
  • 使用系统是CentOS7.2以上版本GeoIP包已安装(rpm -ql GeoIP),但可惜的是它不再自动为您更新库;
  • 如编译报错 "the GeoIP module requires the GeoIP library",请 yum install -y geoip-devel
  • 编译后禁止make install;
  • make 完成后把/root/nginx-1.14.2/objs/nginx 复制到nginx应用程序目录下并覆盖;
[[email protected] nginx-1.14.2]# cd /usr/share/GeoIP
[[email protected] GeoIP]# gzip -d GeoLiteCity.dat.gz
[[email protected] GeoIP]# ln -sv GeoLiteCity.dat GeoCity.dat
[[email protected] ~]# wget http://nginx.org/download/nginx-1.14.2.tar.gz
[[email protected] ~]# tar xf nginx-1.14.2.tar.gz && cd nginx-1.14.2
[[email protected] nginx-1.14.2]# nginx -V
[[email protected] nginx-1.14.2]# ./configure --user=nginx --group=nginx  --with-http_stub_status_module --prefix=/usr/local/nginx --conf-path=/usr/local/nginx/conf/nginx.conf --with-threads --with-http_ssl_module --with-pcre --with-pcre=/usr/local/nginx/modules/pcre-8.30 --with-http_realip_module --with-http_gzip_static_module --with-stream --with-http_slice_module --with-cc-opt=-DTCP_FASTOPEN=23 --add-module=/usr/local/nginx/modules/ngx_cache_purge-2.3 --add-module=/usr/local/nginx/modules/nginx_upstream_check_module --add-module=/usr/local/nginx/modules/file-md5-master --add-module=/usr/local/nginx/modyles/nginx-sticky
--with-http_geoip_module  //此模块即为编译时所加入的静态geoip模块
[[email protected] nginx-1.14.2]# make
[[email protected] nginx-1.14.2]# cp ./objs/nginx /usr/local/nginx/sbin/nginx
[[email protected] nginx-1.14.2]# nginx -V
会显示--with-http_geoip_module此模块证明编译成功

Nginx 配置文件参考

user root root;
worker_processes  auto;
worker_cpu_affinity auto;
error_log /usr/local/nginx/logs/error.log  crit;
pid /var/run/nginx.pid;
worker_rlimit_nofile 65535;

events {
worker_connections 65535;
multi_accept on;
}
http {
include mime.types;
default_type application/octet-stream;
access_log logs/access.log  main;

##定义GeoIP数据库及存储路径##
geoip_city /usr/share/GeoIP/GeoCity.dat;
geoip_proxy 192.168.0.0/24;
geoip_proxy 192.168.1.0/24;
geoip_proxy_recursive on;

##结合GeoIP数据库并引入map指令来自定义变量,充分发挥作用##
map $geoip_city $no_allowed_region {
default 1;
Shanghai yes;
Beijing yes;
Tianjin yes;
}

server {
listen 80;
listen 443 default_server;
server_name you.domain.com;
ssl on;
ssl_certificate  /usr/local/nginx/ssl/you.domain.com.crt;
ssl_certificate_key  /usr/local/nginx/ssl/you.domain.com.key;
ssl_session_timeout 5m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;
ssl_prefer_server_ciphers on;
root   /html;
index index.html index.htm;
try_files /index_$geoip_city.html ./index.html;

location /static {
root   /data;
    }
location ~ ^/api/pad/available {
default_type application/json;
return 200 ‘{"success":true}‘;
    }
#变量判断#
location /files/pad/yim-1.2.9.apk {
imit_conn addr 10;
limit_rate 100k;
if ($no_allowed_region = 1) {
return 550;
        }
    }
#变量判断#
location /files/pad/yimpad-version.json {
limit_conn addr 10;
limit_rate 100k;
if ($no_allowed_region = 1) {
return 550;
        }
    }
location ~ ^/static/water/material {
root       /data/files;
limit_conn addr 10;
limit_rate 100k;
        }
    }
}
  • 匹配apk文件:

    当访问的是/files/pad/yimi-1.2.9.apk文件时以下配置段被命中。if判断读取map指令中源变量$geoip_city的值去匹配后一个变量$no_allowed_region的值,如匹配成功则放行。其它或空则匹配默认规则,默认规则值是 default 1,如果匹配到默认规则的话在http响应状态码中则返回550作为警示码;
    location /files/pad/yimi-1.2.9.apk {
    root /data;
    limit_conn addr 10;
    limit_rate 100k;
    if ($no_allowed_region = 1) {
    return 550;
        }
    }
  • 匹配json文件:
    当访问的是/files/pad/yimipad-version.json文件时以下配置段被命中。if判断读取map指令中源变量$geoip_city的值去匹配后一个变量$no_allowed_region的值,如匹配成功则放行。其它或空则匹配默认规则,默认规则值是 default 1,如果匹配到默认规则的话在http响应状态码中则返回550作为警示码;
    location /files/pad/yimipad-version.json {
    root /data;
    limit_conn addr 10;
    limit_rate 100k;
    if ($no_allowed_region = 1) {
    return 550;
        }
    }
    默认黑名单机制 default 1,即所有请求全部拒绝。只有在map配置段中添加 CITY = YES时规则才有效;

从GeoIP升级到GeoIP2

  • 安装开发包组
[[email protected] ~]# yum groupinstall -y Development Tools
[[email protected] ~]# yum install -y pcre-devel openssl openssl-devel zlib-devel
  • 下载编译libmaxmindb依赖库
official help site https://github.com/maxmind/libmaxminddb
[[email protected] ~]# cd /usr/local/src && git clone --recursive https://github.com/maxmind/libmaxminddb
[[email protected] ~]# cd libmaxminddb
[[email protected] ~]# ./bootstrap
[[email protected] ~]# ./configure
[[email protected] ~]# make
[[email protected] ~]# make install
[[email protected] ~]# sh -c "echo /usr/local/lib  >> /etc/ld.so.conf.d/local.conf"
[[email protected] ~]# ldconfig
  • 平滑升级Nginx并编译(ngx_http_geoip2_module)模块
参考"Nginx+GeoIP Modules+GeoIP Datebase"编译nginx的方法,一定要带上原有参数
[[email protected] ~]# nginx -V
[[email protected] ~]# cd /usr/local/nginx/modules
[[email protected] ~]# git clone --recursive https://github.com/leev/ngx_http_geoip2_module
[[email protected] ~]# cd /root/nginx-1.14.2
[[email protected] nginx-1.14.2]# ./configure --原有参数 --add-module=/usr/local/nginx/modules/ngx_http_geoip2_module
[[email protected] nginx-1.14.2]# make
[[email protected] nginx-1.14.2]# mv /usr/local/nginx/sbin/nginx{,.baks}
[[email protected] nginx-1.14.2]# cp objs/nginx /usr/local/nginx/sbin
[[email protected] nginx-1.14.2]# make upgrade
如果在make upgrade的时候报错 "make: *** [upgrade] error 1" 先完全kill掉nginx主进程,然后使用-c选项启动nginx,再次执行make upgrade
[[email protected] ~]# /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
这里把ngx_http_geoip2_module构建为静态模块,如果构建为动态模块需Nginx版本大于1.9.11+
  • 下载libmaxminddb数据库文件
official help site https://dev.maxmind.com/geoip/geoip2/geolite2
[[email protected] ~]# wget https://geolite.maxmind.com/download/geoip/database/GeoLite2-City.tar.gz
[[email protected] ~]# wget https://geolite.maxmind.com/download/geoip/database/GeoLite2-Country.tar.gz
[[email protected] ~]# tar xf GeoLite2-City.tar.gz -C /usr/share/GeoIP2
[[email protected] ~]# tar xf GeoLite2-Country.tar.gz -C /usr/share/GeoIP2
  • 修改nginx配置替换GeoIP内容如下
##geoip2 with##
geoip2 /usr/share/GeoIP2/GeoLite2-City.mmdb {
auto_reload 60m;
$geoip2_metadata_city_build metadata build_epoch;
$geoip2_data_city_name city names en;
$geoip2_data_city_name default=Shanghai city names en;
}

##map geoip##
map $geoip2_data_city_name  $default_city_list {
default 1;
Shanghai yes;
}

##server or location##
if ($default_city_list = 1) {
        return 770;
}
  • 重载nginx配置文件 nginx -s reload

测试命令 mmdblookup

  • 测试在mmdb数据库中查找数据路径(国家/地区名称en)
  • mmdblookup --file /usr/share/GeoIP2/GeoLite2-City.mmdb --ip 49.7.20.53

原文地址:https://blog.51cto.com/51eat/2465005

时间: 2024-10-14 02:04:23

客户端灰度发布,NGINX+GeoIP2+GeoIP Database的相关文章

使用Nginx+Lua实现Web项目的灰度发布

使用Nginx+Lua实现Web项目的灰度发布 Nginx编译安装Lua模块 一.安装LUA环境及相关库 官方网站:https://github.com/openresty/lua-nginx-module 1.LuaJIT wget http://luajit.org/download/LuaJIT-2.0.2.tar.gz make && make install PREFIX=/usr/local/LuaJIT # vim /etc/profile export LUAJIT_LIB

互联网产品灰度发布

互联网产品灰度发布 关于2016年5月15日,DevOps成都站|架构与运维峰会活动总结 1. 前言 2 2. 灰度发布定义 5 3. 灰度发布作用 5 4. 灰度发布步骤 5 5. 灰度发布测试方法 6 6. 灰度发布引擎 6 7. 灰度发布常见问题 8 7.1. 以偏概全 8 7.1.1. 问题特征: 8 7.1.2. 解决方案: 8 7.2. 知识的诅咒 9 7.2.1. 问题特征: 9 7.2.2. 解决方案: 9 7.3. 发布没有回头路可走 9 7.3.1. 问题特征: 9 7.3.

基于Geoip城市的灰度发布

1.安装epel源 wget https://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm rpm -ivh epel-release-6-8.noarch.rpm 2.首先安装 MaxMind 的 GeoIP 库,其官网是: http://www.maxmind.com,MaxMind 提供了免费的 IP 地域数据库(GeoIP.dat),不过这个数据库文件是二进制的 yum install GeoIP G

nginx 根据IP 进行灰度发布

灰度发布,简单来说,就是根据各种条件,让一部分用户使用旧版本,另一部分用户使用新版本. nginx 的语法本身可以看作是一门小型的编程语言,通过简单的编程,可以轻松实现基于IP的灰度发布. 需求:搭建准生产环境,供开发人员/运维在线上做最后的调整.如果OK,直接用rsync推送至生产环境. 条件:办公室网络出口有固定IP 解决办法: nginx 负载均衡器判断客户端IP地址, 如果是办公室IP,则反向代理到准生产环境: 如果不是,则反向代理到生产环境. 1 2 3 4 5 6 7 8 9 10

nginx+lua+redis实现灰度发布_test

nginx+lua+redis实现灰度发布: 灰度发布是指在黑白之间能够平滑过渡的一种方式 AB test就是一种灰度发布方式,让一部分用户继续用A,一部分用户开始用B,如果用户对B没有什么反对意见,那么逐步扩大范围,把所有用户都迁移到B上面 来.灰度发布可以保证整体系统的稳定,在初始灰度的时候就可以发现.调整问题,以保证其影响度. 灰度发布可以保证应用系统的稳定,降低产品升级影响的用户范围:也可以按照一定的策略让部分用户提前参与产品测试,从而提早获取到用户的反馈,完善应用功能 原理:使用ngi

Nginx配置之负载均衡、限流、缓存、黑名单和灰度发布

一.Nginx安装(基于CentOS 6.5) 1.yum命令安装 yum install nginx –y(若不能安装,执行命令yum install epel-release) 2. 启动.停止和重启 service nginx startservice nginx stopservice nginx restart浏览器中 输入服务器的 ip 地址,即可看到相应信息 3. 其他信息 rpm -ql nginx 来查看安装路径yum remove nginx 来卸载 nginx -s rel

Nginx详解二十四:Nginx深度学习篇之灰度发布

实战场景 - 灰度发布 灰度发布的作用:按照一定的关系区别,分部分的代码进行上线,使代码的发布能平滑过渡上线实现方式: 1.用户的信息cookie等信息区别 2.根据用户的IP地址 安装memcached:yum -y install memcached 准备好两个tomcat,9090代表生产环境,8080代表预发布环境 为避免冲突,修改tomcat9090的端口号 这里分别在同个tomcat/webapp/ROOT/下放了同样内容的jsp文件 把8080下的jsp问价内容改一下区别于9090

基于cookie在nginx实现业务灰度发布

基于cookie在nginx实现业务灰度发布 背景 灰度发布是指在黑与白之间,能够平滑过渡的一种发布方式. 灰度发布可以保证整体系统的稳定, 在初始灰度的时候就可以发现.调整问题,以保证其影响度. 业务存在灰度发布的需求, 可以通过nginx+lua形式实现业务的灰度发布, 目前这一形式已在广平互动广告相关业务已经实现. 流程 用户使用帐号登录后,判断用户帐号是否在灰度发布的名单中,如果再则给用户的cookie中增加灰度发布标识,然后刷新页面. 当用户访问页面时,业务接入层的nginx方向代理会

使用nginx实现的灰度发布思路研究(待实践)

灰度发布也叫 A/B 测试,原理是一套系统在实现了负载均衡,全国节点都部署了系统之后,可以在新功能上线后,让一小部分用户先使用,从中收集使用信息来做对比和发现bug,及时调整,最终分发到全国的节点. 实现灰度发布的几个思路: 1.以nginx为例的分流,IP是最终的关键,从而以IP围绕中心,可以衍生出很多定义,比如用户标识.用户分组.设备ID及分组等,但是最终还是离不开IP去分流. 2.nginx支持模块开发,如果在一套成熟的系统中,可以开发自己的模块,从而脱离IP为分流导向,指定自己的精确分流