干货| 动态更新(热更新)机制及技术原理分享

Posted lydia77

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了干货| 动态更新(热更新)机制及技术原理分享相关的知识,希望对你有一定的参考价值。

近期工作提到动态更新比较多,今天也借此机会,梳理一下相关的机制原理同大家分享。

动态机制及技术原理

动态研发模式就是一种基于云端的移动应用开发方法,主要能让开发者快速构建和发布多端的移动应用,实现业务的敏捷迭代和热更新,提高用户体验和运营效率。实现动态更新的原理可以分为两个部分:应用程序更新机制和资源更新机制。

1、应用程序更新机制

应用程序更新机制是指如何更新应用程序的代码逻辑和业务功能。通常情况下,应用程序的更新包括两部分:客户端代码更新和服务端数据更新。

1)客户端代码更新

是指应用程序的逻辑代码和业务功能代码的更新,通过应用程序的热更新机制实现。应用程序在启动时会检查服务器上是否有新版本的客户端代码,如果有,则下载新的代码,并通过热更新机制进行替换,从而实现应用程序的更新。

较常见的有我们使用微信小程序时版本更新会提醒重新打开。

 

 

2)服务端数据更新

指应用程序所需的数据的更新,通常情况下,服务端数据更新通过应用程序的数据同步机制实现。应用程序在启动时会检查服务器上是否有新的数据,如果有,则通过数据同步机制进行更新,从而实现应用程序的更新。

2、资源更新机制

资源更新机制是指如何更新应用程序所需的资源文件,例如图片、音频、视频等。通常情况下,资源更新机制也是通过应用程序的热更新机制实现。

资源文件的更新一般分为两种方式:增量更新和全量更新。增量更新是指只更新部分资源文件,例如只更新某个图片或音频文件,而全量更新则是指更新所有的资源文件。

王者荣耀就是用到的增量更新机制。

 

 

在实际应用中,增量更新的优点是更新速度快、网络流量小,但缺点是需要开发人员手动维护版本管理。而全量更新的优点是版本管理简单,但缺点是更新速度慢、网络流量大。

总之,移动端动态更新背后的原理主要涉及应用程序更新机制和资源更新机制。在实际应用中,需要根据具体的业务需求和技术情况选择合适的更新方式,以实现应用程序的高效更新和优化。

动态更新模式的价值

主要价值体现在以下几个方面:

  1. 快速响应市场需求:快速响应市场需求和用户反馈,通过持续的迭代和优化来提高产品质量和用户体验。
  2. 降低开发成本:通过远程更新来实现应用程序的热更新,从而降低应用程序的维护和开发成本。
  3. 提高应用程序的稳定性和安全性:通过远程更新来及时修复应用程序中的漏洞和问题,从而提高应用程序的稳定性和安全性。
  4. 适应不同的平台和设备:可以通过HTML5和小程序容器来适应不同的平台和设备,从而提高应用程序的可访问性和可用性。

上面也提到移动端动态研发模式是一种利用 HTML 或小程序实现移动应用的快速开发和更新的方法,下面也说下他们的具体情况。

HTML 5 模式

HTML5大家太熟悉了,就不做过多的介绍,它支持多种设备和平台上的网页应用程序开发,并为开发人员提供了一种更加简单、灵活、跨平台的开发方式。在移动端动态研发模式中,HTML5的应用非常广泛,主要表现在以下几个方面:

  1. 跨平台支持:HTML5可以在多个平台上运行,包括iOS、Android和Windows等,这大大提高了应用程序的可访问性和可用性。
  2. 简单易用:HTML5的开发工具和技术相对来说更加容易掌握和理解,而且开发过程中可以使用开源工具库和框架来提高效率。
  3. 热更新:HTML5应用可以通过远程更新来实现应用程序的热更新,这样就可以快速响应用户的需求和反馈,同时降低应用程序的维护成本。

但是,HTML5也存在一些缺点,比如性能较差、安全性低等,这些问题可能会影响应用程序的用户体验和安全性能。

小程序模式

小程序大家也很熟悉,不过大家可能会疑惑小程序只能运行在微信、支付宝等超级App中,和我们自己的App关系不大,但实际上自己的 App 中也能很快的跑小程序,例如集成FinClip SDK就可以实现,后续通过一个管理后台直接上下架小程序。

上面的技术也叫小程序容器,是一种将小程序嵌入到原生应用中的技术,它可以利用专门的运行时环境来执行小程序代码,同时提供原生能力的调用接口,让小程序可以访问设备的相机、定位、通讯录等功能。

  1. 跨平台支持:小程序容器可以在多个平台上运行,包括iOS、Android和Windows等,这大大提高了应用程序的可访问性和可用性。
  2. 轻量级应用:小程序容器可以提供快速、高效的应用程序开发方式,同时还可以减少应用程序的体积和资源占用,从而提高应用程序的性能和响应速度。
  3. 热更新:小程序容器可以通过远程更新来实现应用程序的热更新,这样就可以快速响应用户的需求和反馈,同时降低应用程序的维护成本。

小程序容器的不足主要在开发方面,需要掌握一定的前端技术和小程序开发规范,受限于小程序开发规范和平台限制,一些高级特性和功能可能无法实现,不过在自己App内引入小程序后可以规避这个问题。

总之,动态研发模式在移动端应用程序开发中具有重要的价值和作用,可以帮助企业快速响应市场需求、降低开发成本、提高应用程序的稳定性和安全性、适应不同的平台和设备。

技术分享|集成开放平台使用Consul Watch机制实现配置热更新


源宝导读:在微服务架构体系中,由于微服务众多,服务之间又有互相调用关系,因此,一个通用的分布式配置管理是必不可少的。本文将介绍如何使用Consul Watch机制实现配置集中管理与热更新。

前言

随着程序功能的日益复杂,程序的配置日益增多:各种功能的开关、参数的配置、服务器的地址等等,对程序配置的期望值也越来越高:配置修改后实时生效,分环境、分集群管理配置,代码安全、审核机制。在这样的大环境下,传统的通过配置文件、数据库等方式已经越来越无法满足开发人员对配置管理的需求。所以,配置中心应运而生。

在微服务架构体系中,由于微服务众多,服务之间又有互相调用关系,因此,一个通用的分布式配置管理是必不可少的。一般来说,配置管理需要解决配置集中管理、在系统运行期间可实现动态配置、配置修改后支持自动刷新等问题。

一、Consul在集成开放平台的使用场景

天际集成开放平台深度集成Consul,实现微服务架构中的以下场景:

1 .服务注册:Consul提供了通过DNS或者HTTP接口的方式将我们的服务信息注册给Consul

2 .服务发现:Consul提供了通过DNS或者HTTP接口的方式查询发现注册的服务。这样外部可以很容易的发现它所依赖的服务

3.服务负载均衡:Consul的服务注册是集群式的。我们可用通过负载均衡算法从Consul注册的服务列表中负载出一个可以被访问的服务

4 .Key/Value配置中心:应用程序可以根据自己的需要使用Consul提供的Key/Value存储。Consul提供了简单易用的HTTP接口,结合其他工具可以实现动态配置、功能标记、领袖选举等等功能

5 .健康检查:Consul的Client可以提供任意数量的健康检查,可以与给定的服务相关联(HTTP服务是否返回200)。系统可以使用这些信息来监视集群的健康状况,服务发现组件可以使用这些信息将流量从不健康的主机路由出去

二、Consul K/V查询与Blocking Query

2.1 Consul提供的Watch类型

1. Key – 监视指定K/V键值对

2. Keyprefix – 监视指定的Keyprefix

3. Services – 监视服务列表

4.nodes – 监控节点列表

5. service – 监视服务实例

6. checks- 监视健康检查的值

2.2 Consul K/V 查询

2.2.1 K/V查询

通过Consul提供的K/V HTTP API。我们可以很容易的对Consul的K/V进行写入,修改,查询操作。

通过Consul管理控制台,我们新建一个Key为Config的配置项并设置值为 {"title":"测试标题","MaxTaskCount":3}。

调用Consul K/V查询API http://127.0.0.1:8500/v1/kv/{key}可以查询key下Value的值,此处,我们需要查询是Key是Config。所以,完整的Uri是http://127.0.0.1:8500/v1/kv/Config。

查询结果 

 {
    "LockIndex": 0,
    "Key": "Config",
    "Flags": 0,
    "Value": "ewoidGl0bGUiOiLmtYvor5XmoIfpopgiLAoiTWF4VGFza0NvdW50IjozCn0=",
    "CreateIndex": 7319758,
    "ModifyIndex": 7319803
 }

通过查询结果可以获取Config的Value信息,HTTP API查询的Value一般是字节的Base64表现形式。当然,在实际的编码过程中,我们不会直接使用HTTP API调用。而是通过Consul Client SDK进行调用。

C#使用Consul Client SDK查询K/V 

 var uri = new UriBuilder("http", "127.0.0.1", 8500);
IConsulClient client = new ConsulClient(config => config.Address = uri.Uri);
var response =await client.KV.Get("Config");
var value = string.Empty;


 if (response?.StatusCode == System.Net.HttpStatusCode.OK)
 {
 value = Encoding.UTF8.GetString(response.Response?.Value);
}

上述查询代码可以获取Config的真实配置值 {"title":"测试标题","MaxTaskCount":3}。

2.2.2 Keyprefix查询

2.2.1章节中介绍了如何进行Consul的K/V查询。而在实际的使用过程中,不仅仅会进行的K/V查询。还会使用Keyprefix方式来查询某个prefix下的所有K/V信息。

在Consul管理控制台,新建Key Students,在Students Key下新建多个K/V,如下图所示:

设置查询的prefix为Students,查询结果应该为Students下配置的所有的K/V数据列表。

C#使用Consu Client Sdk执行Keyprefix查询 

var uri = new UriBuilder("http", "127.0.0.1", 8500);
            IConsulClient client = new ConsulClient(config => config.Address = uri.Uri);
            var response =await client.KV.List("Students");
            var kvList = new List<string>();


            if (response?.StatusCode == System.Net.HttpStatusCode.OK)
            {
                foreach (var kVPair in response.Response)
                {
                    if (kVPair.Value != null)
                    {
                        var value = Encoding.UTF8.GetString(kVPair.Value);
                        kvList.Add(value);
                    }
                }
            }


            var outPutString = JsonSerializer.Serialize(kvList);

查询结果 

[
    {
        "name":"Nick",
        "address":"test address",
        "age":18
    },
    {
        "name":"Tom",
        "address":"test address",
        "age":18
    }
]

2.3 Consul Blocking Query

上述2.1、2.2章节介绍了Consul的K/V查询的两种方式。要实现配置实时更新通知Consul K/V查询只是第一步,而下面要介绍的就是关键的第二步,Consul的Blocking Query。

Blocking Query官方定义:

Many endpoints in Consul support a feature known as "blocking queries". A blocking query is used to wait for a potential change using long polling. Not all endpoints support blocking, but each endpoint uniquely documents its support for blocking queries in the documentation.

Endpoints that support blocking queries return an HTTP header named X-Consul-Index. This is a unique identifier representing the current state of the requested resource.

On subsequent requests for this resource, the client can set the index query string parameter to the value of X-Consul-Index, indicating that the client wishes to wait for any changes subsequent to that index.

When this is provided, the HTTP request will "hang" until a change in the system occurs, or the maximum timeout is reached. A critical note is that the return of a blocking request is no guarantee of a change. It is possible that the timeout was reached or that there was an idempotent write that does not affect the result of the query.

In addition to index, endpoints that support blocking will also honor a wait parameter specifying a maximum duration for the blocking request. This is limited to 10 minutes. If not set, the wait time defaults to 5 minutes. This value can be specified in the form of "10s" or "5m" (i.e., 10 seconds or 5 minutes, respectively). A small random amount of additional wait time is added to the supplied maximum wait time to spread out the wake up time of any concurrent requests. This adds up to wait / 16 additional time to the maximum duration.

简单来说就是当客户端请求Consul获取K/V时,需要携带一个版本号信息,Consul会比较这个客户端版本号是否和Consul服务端的版本号一致,如果一致,则Consul会阻塞这个请求,直到Consul中的K/V发生变化,或者到达阻塞时间上限;如果版本号不一致,则立即返回。这个阻塞时间默认是5分钟,支持自定义。

利用阻塞查询的机制,我们可以发起一个“挂起”的查询。这个查询直到K/V的值发生变更才会返回,这样,查询发起方既能收到K/V值发生变更的通知,又能接收变更后的最新值。

Consul Blocking Query查询 

Task.Factory.StartNew(async () => 
 {
    ulong waitIndex = 0;
    var uri = new UriBuilder("http", "10.20.21.13", 8500);
    IConsulClient client = new ConsulClient(config => config.Address = uri.Uri);


     while (true)
     {
         var response = await client.KV.Get("Config", new QueryOptions { WaitIndex = waitIndex });


          if (response.StatusCode == System.Net.HttpStatusCode.OK)
            {
               if (response.Response?.Value != null)
                  {
                       var value = Encoding.UTF8.GetString(response.Response?.Value);
                            waitIndex = response.Response.ModifyIndex;
                        }
                    }
                }
            });

上述代码的Blocking Query经历下面步骤:

1 .声明客户端查询版本号,默认值0

2 .执行初始查询,获取K/V值

3 .将查询结果中Consul服务端该K/V的最新版本号赋值给客户端查询版本号

4 .使用最新的客户端版本号进行阻塞查询

5 .最新客户端发起的查询将会"挂起",直到Config中Value值发生变更,查询才会返回

上述操作是在一个后台循环线程中运行的,所以,在”挂起“的查询返回时即完成一次K/V更改通知。随后进入下一次查询”挂起操作“,直到又一次发生变更。这样,程序在运行期间便能一直保持对某个Key的Blocking Query达到配置更改通知的目的。

三、集成开放平台使用Consul Blocking Query实现实时生效配置中心

第2节描述了如何使用Consul的Blocking Query实现配置实时更改通知。在集成开放平台中,不同微服务的配置会放置在Consul的不同路径下。现在各服务配置之间的隔离,每个服务在启动时会对需要在运行期间热更新的配置发起Blocking Query,当配置管理模块更改了服务监控的配置时,服务“挂起”的配置查询就会收到更新通知。

四、后续思考

整体来说,集成开放平台利用Consul实现的配置实时通知还属于使用阶段。而配置行为,配置管理,配置Consul更改通知等等并未独立为单独的配置服务与配置管理模块。配置相关的代码还是分散在各服务中。在之后的架构演变中,可以考虑将配置单独出一个配置服务与管理。而各微服务使用的只应该是配置服务对应的SDK。这样整体架构就指责清晰,领域独立了。

----- END ------

作者简介

刘同学: 研发工程师,目前负责集成开放平台相关工作。

也许您还想看:

Jekins持续集成在ERP研发中的应用实践

基于PaaS平台的多应用自集成方案之公共数据集成

更多明源云·天际开放平台场景案例与开发小知识,可以关注明源云天际开发者社区公众号:

【DevOps】获取流水线部署信息,查看部署快人一步

【建模】ERP日志分表,提升海量日志存取性能

以上是关于干货| 动态更新(热更新)机制及技术原理分享的主要内容,如果未能解决你的问题,请参考以下文章

技术分享|集成开放平台使用Consul Watch机制实现配置热更新

自研 iOS 热更新机制——OCPack技术方案总结

Android热修复:底层替换类加载原理总结 及 DexClassLoader类加载机制源码探索

Android热修复:底层替换类加载原理总结 及 DexClassLoader类加载机制源码探索

热更新机制

腾讯Bugly干货分享美团大众点评 Hybrid 化建设