黎旭新博客

    微信小程序转换uni-app详细指南、小程序转uni-app转换器、wepy转uni-app

    2019年08月05日 | 作者: | 评论:0人 | 浏览:330

    微信小程序转app

    2019年08月05日 | 作者: | 评论:0人 | 浏览:209

    如何使用apktool反编译APK

    2019年08月05日 | 作者: | 评论:0人 | 浏览:201

    阿里平头哥首颗芯片玄铁910出炉,可应用于5G和AI

    2019年07月26日 | 作者: | 评论:0人 | 浏览:400
    阿里平头哥首颗芯片玄铁910出炉,可应用于5G和AI

    7月25日消息,阿里巴巴旗下半导体公司平头哥正式发布玄铁910(XuanTie910),称玄铁910目前业界性能最强的一款RISC-V处理器。玄铁910可以用于设计制造高性能端上芯片,应用于5G、人工智能以及自动驾驶等领域。“玄铁重剑”是金庸笔下第一神剑,最早为“独孤求败”所用,其重达六十四斤,剑上...

    移动互联网结束,“小程序互联网”开启

    2019年07月07日 | 作者: | 评论:0人 | 浏览:294
    移动互联网结束,“小程序互联网”开启

    巨头会战小程序,下半场战事仍将继续中国移动互联网经历过去10年发展,近乎完美地将十亿计用户使用习惯培养起来,尤其是消费互联网,更是被开垦成了一块儿商业熟土,直至近年愈发明显地出现用户红利触顶、难以再现爆发式增长的可能。QuestMobile发布的2019年中国移动互联网春季报告显示,国内移动互联网用...

    使用Nginx+Lua(OpenResty)开发高性能Web应用

    2019年06月08日 | 作者: | 评论:0人 | 浏览:240
    使用Nginx+Lua(OpenResty)开发高性能Web应用

    如上图,我们首先通过LVS+HAProxy将流量转发给核心Nginx 1和核心Nginx 2,即实现了流量的负载均衡,此处可以使用如轮训、一致性哈希等调度算法来实现负载的转发;然后核心Nginx会根据请求特征如“Host:item.jd.com”,转发给相应的业务Nginx节点如单品页Nginx 1。此处为什么分两层呢?

    1、核心Nginx层是无状态的,可以在这一层实现流量分组(内网和外网隔离、爬虫和非爬虫流量隔离)、内容缓存、请求头过滤、故障切换(机房故障切换到其他机房)、限流、防火墙等一些通用型功能;

    2、业务Nginx如单品页Nginx,可以在在业务Nginx实现业务逻辑、或者反向代理到如Tomcat,在这一层可以实现内容压缩(放在这一层的目的是减少核心Nginx的CPU压力,将压力分散到各业务Nginx)、AB测试、降级;即这一层的Nginx跟业务有关联,实现业务的一些通用逻辑。

    不管是核心Nginx还是业务Nginx,都应该是无状态设计,可以水平扩容。

    业务Nginx一般会把请求直接转发给后端的业务应用,如Tomcat、PHP,即将请求内部转发到相应的业务应用;当有的Tomcat出现问题了,可以在这一层摘掉;或者有的业务路径变了在这一层进行rewrite;或者有的后端Tomcat压力太大也可以在这一层降级,减少对后端的冲击;或者业务需要灰度发布时也可以在这一层Nginx上控制。

    、单机闭环

    所谓单机闭环即所有想要的数据都能从本服务器直接获取,在大多数时候无需通过网络去其他服务器获取。

    如上所示,主要有三种应用模式:

    2.1、第一张图应用场景是Nginx应用谁也不依赖,比如我们的Cookie白名单应用,其目的是不在白名单中的Cookie将被清理,防止大家随便将Cookie写到jd.om根下;大家访问http://www.jd.com时,会看到一个http://ccc.jd.com/cookie_check的请求用来清理Cookie的;对于这种应用非常简单,不需要依赖数据源,直接单应用闭环即可。

    2.2、第二张图,是读取本机文件系统,如静态资源合并:比如访问http://item.jd.com/1856584.html ,查看源码会发现【<link type="text/css" rel="stylesheet" href=" //misc.360buyimg.com/jdf/1.0.0/unit/??ui-base/1.0.0/ui-base.css,shortcut/2.0.0/shortcut.css,global-header/1.0.0/global-header.css,myjd/2.0.0/myjd.css,nav/2.0.0/nav.css,shoppingcart/2.0.0/shoppingcart.css,global-footer/1.0.0/global-footer.css,service/1.0.0/service.css "/>】这种请求,即多个请求合并为一个发给服务端,服务端进行了文件资源的合并;

    目前有成熟的Nginx模块如 nginx-http-concat 进行静态资源合并;因为我们使用了OpenResty,那么我们完全可以使用Lua编写程序实现该功能,比如已经有人写了nginx-lua-static-merger 来实现这个功能。

    还一些业务型应用场景如下图所示

    商品页面是由商品框架和其他维度的页面片段(面包屑、相关分类、商家信息、规格参数、商品详情)组成;或者首页是由首页框架和一些页面片段(分类、轮播图、楼层1、楼层N)组成;分维度是因为不同的维度是独立变化的。对于这种静态内容但是需要进行框架内容嵌入的方式,Nginx自带的SSI(Server Side Include)可以很轻松的完成;也可以使用Lua程序更灵活的完成(读取框架、读取页面片段、合并输出)。

    比如商品页面的架构我们可以这样:

    首先接收到商品变更消息,商品页面同步Worker会根据消息维度生成相关的页面推送到Nginx服务器;Nginx应用再通过SSI输出。目前京东商品详情页没有再采用这种架构,具体架构可以参考《 构建需求响应式亿级商品详情页 》。

    对于首页的架构是类似的,因为其特点(框架变化少,楼层变化较频繁)和个性化的要求,楼层一般实现为异步加载。

    2.3、 第三张图和第二张图的不同处是不再直接读取文件系统,而是读取本机的Redis或者Redis集群或者如SSDB这种持久化存储或者其他存储系统都是可以的,比如直接说的商品页面可以使用SSDB进行存储实现。文件系统一个很大的问题是当多台服务器时需要Worker去写多台服务器,而这个过程可以使用SSDB的主从实现。

      此处可以看到,不管是图二还是图三架构,都需要Worker去进行数据推送;假设本机数据丢了可怎么办?因此实际大部分应用不会是完全单机闭环的,而是会采用如下架构:



    即首先读本机,如果没数据会回源到相应的Web应用从数据源拉取原始数据进行处理。这种架构的大部分场景本机都可以命中数据,只有很少一部分情况会回源到Web应用。

    如京东的实时价格/动态服务就是采用类似架构。

    、分布式闭环

    单机闭环会遇到如下两个主要问题: 1、数据不一致问题(比如没有采用主从架构导致不同服务器数据不一致);2、遇到存储瓶颈(磁盘或者内存遇到了天花板)。

    解决数据不一致的比较好的办法是采用主从或者分布式集中存储;而遇到存储瓶颈就需要进行按照业务键进行分片,将数据分散到多台服务器。

    如采用如下架构,按照尾号将内容分布到多台服务器。

    即第一步先读取分布式存储(JIMDB是京东的一个分布式缓存/存储系统,类似于Redis);如果不命中则回源到Tomcat集群(其会调用数据库、服务总线获取相关数据)来获取相关数据。可以参考《 构建需求响应式亿级商品详情页 》来获取更详细的架构实现。

    JIMDB集群会进行多机房主从同步,各自机房读取自己机房的从JIMDB集群,如下图

    、接入网关

    接入网关也可以叫做接入层,即接收到流量的入口,在入口我们可以进行如下事情:

    4.1 、核心接入Nginx 会做如下事情:

    1、动态负载均衡;1、普通流量走一致性哈希,提升命中率;热点流量走轮训减少单服务器压力;2、根据请求特征将流量分配到不同分组并限流(爬虫、或者流量大的IP);3、动态流量(动态增加upstream或者减少upstream或者动态负载均衡)可以使用balancer_by_lua或者微博开源的upsync;

    2、防DDOS攻击限流:可以将请求日志推送到实时计算集群,然后将需要限流的IP推送到核心Nginx进行限流;

    3、非法请求过滤:比如应该有Referer却没有,或者应该带着Cookie却没有Cookie;

    4、请求聚合:比如请求的是http://c.3.cn/proxy?methods=a,b,c,核心接入Nginx会在服务端把Nginx并发的请求并把结果聚合然后一次性吐出;

    5、请求头过滤:有些业务是不需要请求头的,因此可以在往业务Nginx转发时把这些数据过滤掉;

    6、缓存服务:使用Nginx Proxy Cache实现内容页面的缓存;

    4.2 、业务Nginx 会做如下事情:

    1、缓存:对于读服务会使用大量的缓存来提升性能,我们在设计时主要有如下缓存应用:首先读取Nginx本地缓存  Shared Dict或者Nginx Proxy Cache,如果有直接返回内容给用户;如果本地缓存不命中,则会读取分布式缓存如Redis,如果有直接返回;如果还是不命中则回源到Tomcat应用读取DB或调用服务获取数据。另外我们会按照维度进行数据的缓存。

    2、业务逻辑:我们会进行一些数据校验/过滤逻辑前置(如商品ID必须是数字)、业务逻辑前置(获取原子数据,然后在Nginx上写业务逻辑)。

    3、细粒度限流:按照接口特征和接口吞吐量来实现动态限流,比如后端服务快扛不住了,那我们就需要进行限流,被限流的请求作为降级请求处理;通过lua-resty-limit-traffic可以通过编程实现更灵活的降级逻辑,如根据用户、根据URL等等各种规则,如降级了是让用户请求等待(比如sleep 100ms,这样用户请求就慢下来了,但是服务还是可用)还是返回降级内容。

    4、降级:降级主要有两种:主动降级和被动降级;如请求量太大扛不住了,那我们需要主动降级;如后端挂了或者被限流了或者后端超时了,那我们需要被动降级。降级方案可以是:1、返回默认数据如库存默认有货;2、返回静态页如预先生成的静态页;3、部分用户降级,告诉部分用户等待下再操作;4、直接降级,服务没数据,比如商品页面的规格参数不展示;5、只降级回源服务,即可以读取缓存的数据返回,实现部分可用,但是不会回源处理;

    5、AB测试/灰度发布:比如要上一个新的接口,可以通过在业务Nginx通过Lua写复杂的业务规则实现不同的人看到不同的版本。

    6、服务质量监控:我们可以记录请求响应时间、缓存响应时间、反向代理服务响应时间来详细了解到底哪块服务慢了;另外记录非200状态码错误来了解服务的可用率。

    京东的交易大Nginx节点、无线部门正在开发的无线Nginx网关、和单品页统一服务都是接入网关的实践,而单品页统一服务架构可以参考《 京东商品详情页服务闭环实践 》。

    、Web 应用

    此处所说的Web应用指的是页面模板渲染类型应用或者API服务类型应用; 比如京东列表页 / 商品详情页 就是一个模板渲染类型的应用,核心业务逻辑都是使用Lua写的,部署到Nginx容器。目前核心业务代码行数有5000多行,模板页面有2000多行,涉及到大量的计算逻辑,性能数据可以参考《 构建需求响应式亿级商品详情页 》。

    整体处理过程和普通Web应用没什么区别:首先接收请求并进行解析;然后读取JIMDB集群数据、如果没有则回源到Tomcat获取;然后进行业务逻辑处理;渲染模板;将响应内容返回给用户。

    三、如何使用Nginx+Lua开发Web应用

    开发一个Web应用我们需要从项目搭建、功能开发、项目部署几个层面完成。

    3.1 、项目搭建

    /export/App/nginx-app -------bin(脚本) ------------start.sh ------------stop.sh -------config(配置文件) ------------nginx.conf ------------domain ----------------nginx_product.conf ------------resources.properties -------lua(业务代码) ------------init.lua ------------product_controller.lua -------template(模板) --------------prodoct.html -------lualib(公共Lua库) ------------jd ----------------product_util.lua ----------------product_data.lua ------------resty ----------------redis.lua ----------------template.lua

    整个项目结构从启停脚本、配置文件、公共组件、业务代码、模板代码几块进行划分。

    、启停脚本

    启停脚本放在项目目录/export/App/nginx-app/bin/下。

    start.sh是启动和更新脚本,即如果nginx没有启动则启动起来,否则reload:

    
    

    在互联网公司,Nginx可以说是标配组件,但是主要场景还是负载均衡、反向代理、代理缓存、限流等场景;而把Nginx作为一个Web容器使用的还不是那么广泛。Nginx的高性能是大家公认的,而Nginx开发主要是以C/C++模块的形式进行,整体学习和开发成本偏高;如果有一种简单的语言来实现Web应用的开...

    招聘要求

    2019年05月14日 | 作者: | 评论:0人 | 浏览:127

    获取APP端中H5代码的方法

    2019年05月14日 | 作者: | 评论:0人 | 浏览:151

    安卓app源码的获取

    2019年05月13日 | 作者: | 评论:0人 | 浏览:104
    安卓app源码的获取

    反编译有一种方式是把dex文件从apk解压出来,得到classes.dex然后用dex2jar把dex文件转换成jar文件: dex2jar.batclasses.dex再把生成的classes.jar文件放到JD-GUI中即可dex2jar下载: https://source...

    微信小程序(webView)嵌入hybirdApp

    2019年05月04日 | 作者: | 评论:0人 | 浏览:141