当前位置: 首页 > news >正文

南充高端网站建设律师个人 网站做优化

南充高端网站建设,律师个人 网站做优化,在婚纱店做网站优化,西安计算机培训机构1. WebAssembly 简介 随着互联网的发展#xff0c;越来越多的应用借助 Javascript 转到了 Web 端#xff0c;但人们也发现#xff0c;随着移动互联网的兴起#xff0c;需要把大量的应用迁移到手机端#xff0c;随着手端的应用逻辑越来越复杂#xff0c;Javascript 的解析…1. WebAssembly 简介 随着互联网的发展越来越多的应用借助 Javascript 转到了 Web 端但人们也发现随着移动互联网的兴起需要把大量的应用迁移到手机端随着手端的应用逻辑越来越复杂Javascript 的解析、编译消耗了大量时间导致页面加载慢应用性能低下的很多问题。 为了解决这些问题Mozilla 的工程师 Alon Zakai 在 2012 年提出了 Asm.js。之后经过几年的发展最终在 2015 年演变成了 WebAssembly。 WebAssembly简写为 Wasm是一种用于堆栈式虚拟机的二进制指令格式。它的设计目的是成为其它编程语言的一个可移植的编译目标以便在 Web 上布署客户端和服务端应用。 这是 WebAssembly 官网上的定义从这个定义中我们可以知道WebAssembly 是一种二进制指令格式。但在日常的讨论中我们也常常把 WebAssembly Text Format 称为 WebAssembly而这种文本格式实际上是一种编程语言。 正式发布后WebAssembly 迎来了迅猛的发展到 2017 年 11 月Mozilla 宣布包括 Chrome、Firefox、Safari 等在内的所有主流浏览器都已经支持 WebAssembly而根据 2021 年 7 月的数据用户正在使用的浏览器中已经有 94% 支持了 WebAssembly。 在得到了浏览器的广泛支持之后一些重量级的应用也被逐渐被移植到了 Web 端其中包括 Google Earth — 一个3D的地图应用 AutoCAD — 一个工业制图的应用 Doom — 一个经典的第一人称的射击游戏 TensorFlow — Google 开源的机器学习框架 … 这些案例也说明 WebAssembly 达到了自己的设计目标——在 Web 上部署桌面上的原生应用。而 WebAssembly 能够获得如此快速的发展得益于它的几个特点 1.1 性能好 接近机器代码的运行速度评测表明WebAssembly 只比原生代码慢大约 10%。 1.2 体积小 加载速度快WebAssembly 是一种紧凑的二进制格式体积通常远小于完成同样功能的 Javascript 代码。 1.3 安全高 WebAssembly 代码运行在沙箱内默认无法进行任何外部访问。 1.4 多语言 WebAssembly 并不限制用户使用何种语言开发只要有相应的编译器任何语言都可以被编译成 WebAssembly。 2. WebAssembly 在后端的应用 在 WebAssembly 的官方定义中“用于堆栈式虚拟机的”这个定语也非常值得关注因为它导致 WebAssembly 这项最初以 Web 端为应用场景以至于名字中都包含“Web”这个词的技术慢慢进入了后端应用的领域。 这是因为从早期的 VMWare WorkStation、VirtualBox到今天的 Docker虚拟化技术一直是云计算的重要基础。所以WebAssembly 作为一种具有很多特点的虚拟机代码格式进入后端应用领域是必然趋势。Docker 的创始人 Solomon Hykes 在 2019 年说“如果 2008 年就有 WASM 和 WASI我们就不用发明 Docker 了”对其在后端应用的前景之看好可见一斑。 当然Solon Hykes 后来也说他的意思不是“WebAssembly 会取代 Docker”这也是当今业界普遍的观点WebAssembly 和 Docker 各有优势互为补充。具体来说 WebAssembly 程序的体积通常只有1M左右而 Docker 镜像则动辄超过100M所以 WebAssembly 具有快得多的加载速度。 WebAssembly 程序的冷启动速度大约是 Docker 容器的 100 倍。 WebAssembly 默认运行在沙箱内任何与外部的交互都只有获得明确的许可之后才能进行具有极佳的安全性。 WebAssembly 模块仅仅是二进制的程序代码不包含操作系统环境所以不可能像在Docker 中那样简单的编译下就能执行。 下面通过实际的示例介绍下如何在后端应用中使用 WebAssembly。 2.1. 在应用中嵌入 WebAssembly 如下图所示不管是 Web 应用还是非 Web 应用要使用 WebAssembly都需要在宿主程序中嵌入 WebAssembly 运行时引擎区别只在于在 Web 应用中这个宿主程序是浏览器而在非 Web 应用中宿主程序是我们自己开发的具体到本文关注的后端应用宿主程序则是我们的后端服务程序。 目前可选的 WebAssembly 运行时引擎有 Wasmtime, WasmEdge, WAVM, Wasmer等很多种各有自己的优势和缺陷。本文将以 Wasmtime 为例介绍如何在以 Go 语言开发的宿主程序中嵌入 WebAssembly。 嵌入 WebAssembly 运行时引擎并实例化 WebAssembly 模块本身非常简单在省略错误处理的情况下只要下面几行代码即可 func createWasmVM(code []byte) { engine : wasmtime.NewEngine() module, _ : wasmtime.NewModule(engine, code) store : wasmtime.NewStore(engine) linker : wasmtime.NewLinker(engine) inst, _ : linker.Instantiate(store, module) _ inst } 其中涉及了实际开发中需要了解的几个重要概念简单介绍如下 引擎engine用于编译和管理模块的全局上下文。 模块module编译后的 WebAssembly 模块。 仓库storeWebAssembly 程序和宿主之间的纽带维护各种关联信息。 实例instance实例化的模块是真正可以执行的程序。 链接器linkerwasmtime 中的一个工具对象用于实例化模块。 虽然上面的代码创建了 WebAssembly 模块的实例并且根据 WebAssembly 的规范模块实例化时就可以执行 WebAssembly 代码但由于安全性的限制其执行结果无法对外输出所以这种“执行”毫无意义。因此我们需要实现宿主程序和 WebAssembly 程序的互操作为 WebAssembly 程序提供输入/输出接口。 2.2. 宿主调用 WebAssembly 假设我们的WebAssembly 程序中有一个名为 sum 的函数接收两个整形变量作为参数返回它们的和则宿主程序可以使用下面的代码来调用这个函数 fn : inst.GetExport(store, “sum”).Func() r, _ : fn.Call(store, 1, 2) fmt.Println(r.(int32)) 虽然不同的宿主开发语言和 WebAssembly 运行时引擎具体的调用方式有区别但运行时引擎的文档一般都有相关说明所以这一步照着文档做就好没有难度。 这里的难点在于如何才能在 WebAssembly 程序中暴露出这个函数以便宿主程序能找到并调用它。前面说过只要有相应的编译器各种语言都可以编译成 WebAssembly但大多数语言设计时并没有考虑 WebAssembly 的需要也就没有提供暴露函数的方法。所以这个问题只能通过特定编译器的非标准扩展来解决。也就是说找到这个非标准扩展是解决问题最关键的一步。但也正由于“非标准”所以相关的资料有时并不容易找到。 作为示例下面给出的是使用 C/C编译器是 emscripten和 AssemblyScript 时对外暴露函数的方法 // C/C EMSCRIPTEN_KEEPALIVE int sum( int a, int b ) { return a b; } // AssemblyScript export function sum( a: i32, b: i32 ): i32 { return a b } 2.3. WebAssembly 调用宿主 与宿主调用 WebAssembly 类似运行时引擎的文档中一般会介绍宿主端如何暴露一个函数给 WebAssembly 程序。 fn : func() { fmt.Println(“hello wasm”) } linker.DefineFunc(store, “easegress”, “hello”, fn) 问题的难度同样在于 WebAssembly 程序中如何使用语言的非标准扩展来导入这个函数下面是 C/C 和 AssemblyScript 中的具体方法 // C/C attribute((import_module(“easegress”), import_name(“hello”))) void hello(); void call_hello() { hello(); } // AssemblyScript external(“easegress”, “hello”) declare function hello(): void export function callHello(): void { hello() } 2.4. 复杂参数传递 宿主和 WebAssembly 程序相互调用对方的函数时也需要传递参数和返回值如果是整数等简单数据类型直接传递即可。但当数据类型是字符串等复杂类型时就会遇到新的问题具体有两点 宿主程序和 WebAssembly 程序的开发语言一般并不相同所以复杂参数的内存布局也不同直接传递的话接收方根本理解不了也就没有办法使用。 由于安全性设计宿主程序和 WebAssembly 程序的内存是隔离开的WebAssembly 程序访问不了宿主的内存。 因为宿主程序可以访问 WebAssembly 的内存所以第二个问题的解决方法是 WebAssembly 程序暴露内存管理的相关函数让宿主来操作 WebAssembly 的内存例如 // C/C EMSCRIPTEN_KEEPALIVE void* wasm_alloc( int size ) { return malloc( size ); } EMSCRIPTEN_KEEPALIVE void wasm_free( void* p ) { free( p ); } // AssemblyScript export function wasm_alloc(size: i32): number { let buf new ArrayBuffer(size) let ptr changetype(buffer) return __pin(ptr) } export function wasm_free(ptr: number): void { __unpin(ptr) } 之后我们可以借助这些内存管理函数并通过序列化/反序列化相关数据类型来传递它们比如在下面 WebAssembly 调用宿主函数的代码中参数和返回值本来各是一个字符串但通过序列化/反序列化之后只要传递它们在 WebAssembly 内存中的地址整数即可 // Host: Go func foo(addr int32) int32 { // … mem : inst.GetExport(store, “memory”).Memory().UnsafeData(store) start : addr for mem[addr] ! 0 { addr } data : make([]byte, addr-start) copy(data, mem[start:addr]) param : string(data) // … result : “result” vaddr, _ : inst.GetExport(store, “wasm_alloc”).Func().Call(store, len(result)1) addr vaddr.(in32) copy(mem[addr:], []byte(result)) mem[addr int32(len(result))] 0 return addr } // WebAssembly: AssemblyScript external(“easegress”, “foo”) declare function foo(addr: number): number export func callFoo(name: string): string { let buf String.UTF8.encode(name ‘’) let addr changetype(buf) addr foo(addr) buf changetype(addr) wasm_free(addr) buf buf.slice(0, buf.byteLength - 1) return String.UTF8.decode(buf) } 2.5. SDK 看了上面宿主程序和 WebAssembly 程序互操作的过程相信大家已经发现它和 RPC 调用的过程非常像。不同的是在 RPC 调用中一系列非常繁琐的序列化/反序列化操作都由工具自动生成代码实现使用者根本无需关心。 而在 WebAssembly 应用的开发中用户也不希望每次都处理那么多的细节。所以作为宿主程序的开发者我们需要为用户提供相关 SDK屏蔽掉底层细节让用户能够专注于业务逻辑的开发。 由于用户可以使用多种语言开发 WebAssembly 应用所以我们需要提供针对不同语言的 SDK或者至少也需要覆盖目标用户使用的主流语言。 2.6. 错误处理 像普通程序一样WebAssembly 程序也会有各种错误虽然作为宿主程序的开发者我们无法预知具体的错误但我们必须把这些错误的影响范围限制在 WebAssembly 虚拟机内部不能让它们影响宿主程序的功能。 宿主程序要防范的第一类错误是 WebAssembly 程序中的死循环。实际场景中其实宿主程序并没有办法判断是否真的出现了死循环所以折衷的解决办法是给 WebAssembly 程序设置一个最大运行时间一旦超过了这个时间还没有结束就认为里面出现了死循环并终止它的执行。终止执行的示例代码如下 ih, _ : store.InterruptHandle() ih.Interrupt() 3. Easegress 中的 WebAssembly Easegress 是 MegaEase 开发的下一代流量型网关具有云原生、高可用、可观测、可扩展等特点。在 Easegress 之前市场上已经有包括 nginx 在内的多个成熟网关产品。但 MegaEase 认为流量调度型网关并不仅仅是一个反向代理还需要能够动态的进行流量编排和调度。此外在具体应用场景中还涉及各种各样的业务逻辑侵入因此必须高度可扩展。 基于以上观点Easegress 从诞生之日就将可扩展性放到了重要位置并在多个层面进行了针对性的设计。 首先在开发语言的选择上我们有C/C/Java/Rust/Go这些主流的静态语言的选项 使用 C/C 或 Rust 肯定会给 Easegress 带来最好的性能但这些语言门槛太高一般用户很难掌握尤其在写业务逻辑的代码上效率实在是太低。也就谈不上通过修改代码来扩展业务逻辑了 Java 易学易用也非常适合写业务逻辑但是体积大而且性能不能满足要求 相对而言Go 简单易学性能也比较好特别是在 Easegress 所处的网络应用领域由于语言本身的特殊设计很多场景下与 C/C 的性能差距基本可以忽略。所以Easegress 最终选择了 Go 作为开发语言。但不管使用什么语言源码级的扩展都不可避免的将用户限制到一门特定的语言而且会涉及重新编译、重新布署、重新启动造成服务的中断。 第二通过外部调用的方式扩展如FaaS。通过云原生的 FaaS 方式的好处是不限制用户的开发语言而且可以让整个架构具有很好的可伸缩性但其缺点是需要引用 Kubernetes 等的比较重的外部依赖导致整个运维非常复杂注Easegress 目前已经支持了 Knative 第三通过嵌入其它语言的解释器进行扩展。这方面Lua 本身就是为嵌入其它程序而设计的具有相应的优势。但我们认为 Lua 也有两个缺点一是本身表现力不够不适合写复杂的业务逻辑二是太小众不是主流语言有相关经验的程序员太少。所以经过权衡Easegress 最终选择了嵌入 WebAssembly主要基于两点考虑一是接近于原生代码的高性能二是不限制用户的开发语言用户可以使用自己喜欢或熟悉的语言开发业务逻辑。 作为使用 WebAssembly 扩展业务逻辑的样例我们之前已经发布了《使用 Easegress WebAssembly 做秒杀》欢迎大家阅读并向我们反馈更多的实际案例。 当然选择了 WebAssembly 意味着我们需要开发多种语言的 SDK目前已经完成了 AssemblyScript SDK 的开发相信在 MegaEase 和整个开源社区的共同努力下我们支持的语言会越来越多。欢迎大家关注我们的开源社区https://github.com/megaease/
http://www.w-s-a.com/news/993314/

相关文章:

  • 厦门网站建设慕枫学做网站需要多久
  • 爱奇艺做任务领vip网站设计广告图片
  • 中科汇联网站建设手册上海公司名称注册查询网
  • 网站建设电子商务课总结和体会关于做网站书籍
  • 仪征网站建设公司哪家好简单网页制作素材图片
  • 甘肃第九建设集团公司网站潍坊个人做网站
  • 如何做后台网站的教程网站建设 关于我们
  • 极速网站建设哪家好连云港百度推广网站建设
  • 医院网站建设的目标wordpress中英文网站模板
  • 门户型网站开发难度网站导航栏有哪些
  • 推荐做任务网站软件定制开发哪家好
  • 邯郸兄弟建站第三方仓储配送公司
  • 商丘家具网站建设wordpress 添加代码
  • 基础建设的网站有哪些内容成都科技网站建设咨询电话
  • 券多多是谁做的网站招聘网站开发模板
  • 网站主机一般选哪种的企业数字展厅
  • 网站建设该如何学衡水建设局网站首页
  • 高校网站建设工作总结番禺网站开发哪家好
  • 苏州 网站的公司wordpress主页代码
  • 怎么用html做图片展示网站外贸网站建设推广费用
  • 可以做本地生活服务的有哪些网站中油七建公司官网
  • 如何建设谷歌网站网站建设优点
  • 做网站的目标是什么产品宣传片制作公司
  • 柳州建设公司网站辽宁建设工程信息网评标专家入库
  • 合肥建设学校官方网站excel导入wordpress
  • 禹城网站设计做网站需要考虑哪些
  • 深圳做营销网站建设wordpress添加文章封面
  • 阿里云的网站建设方案织梦和wordpress哪个安全
  • 聊城网站建设公司电话wordpress怎么重新配置文件
  • 创业如何进行网站建设泰州公司注册