首页 文章 精选 留言 我的

精选列表

搜索[双足行走],共9107篇文章
优秀的个人博客,低调大师

【Android游戏开发之四】Android 游戏框架(一个游戏角色在屏幕行走的demo)

各位童鞋请你们注意:surfaceview中确实有 onDraw这个方法,但是surfaceview不会自己去调用!!! 而我代码中的ondraw 也好 draw 也好,都是我自己定义的一个方法。。。放在线程中不断调用的,一定要注意!! 其实上一篇分析surfaceview的文章就是一个简单的游戏框架了,当然这里再强调一下,简单的游戏框架,所以不要高手们不要乱喷~ 这个Demo是给群里一童鞋写的一个对图片操作以及按键处理,游戏简单框架的一个demo,这里放出给大家分享~ packagecom.himi; importandroid.content.Context; importandroid.content.res.Resources; importandroid.graphics.Bitmap; importandroid.graphics.BitmapFactory; importandroid.graphics.Canvas; importandroid.graphics.Color; importandroid.graphics.Paint; importandroid.util.Log; importandroid.view.KeyEvent; importandroid.view.SurfaceHolder; importandroid.view.SurfaceView; importandroid.view.SurfaceHolder.Callback; publicclassMySurfaceViewextendsSurfaceViewimplementsCallback,Runnable{ privateThreadth=newThread(this); privateSurfaceHoldersfh; privateintSH,SW; privateCanvascanvas; privatePaintp; privatePaintp2; privateResourcesres; privateBitmapbmp; privateintbmp_x=100,bmp_y=100; privatebooleanUP,DOWN,LEFT,RIGHT; privateintanimation_up[]={3,4,5}; privateintanimation_down[]={0,1,2}; privateintanimation_left[]={6,7,8}; privateintanimation_right[]={9,10,11}; privateintanimation_init[]=animation_down; privateintframe_count; publicMySurfaceView(Contextcontext){ super(context); this.setKeepScreenOn(true); res=this.getResources(); bmp=BitmapFactory.decodeResource(res,R.drawable.enemy1); sfh=this.getHolder(); sfh.addCallback(this); p=newPaint(); p.setColor(Color.YELLOW); p2=newPaint(); p2.setColor(Color.RED); p.setAntiAlias(true); setFocusable(true);//备注1 } publicvoidsurfaceCreated(SurfaceHolderholder){ SH=this.getHeight(); SW=this.getWidth(); th.start(); } publicvoiddraw(){ canvas=sfh.lockCanvas(); canvas.drawRect(0,0,SW,SH,p);//备注2 canvas.save();//备注3 canvas.drawText("Himi",bmp_x-2,bmp_y-10,p2); canvas.clipRect(bmp_x,bmp_y,bmp_x+bmp.getWidth()/13,bmp_y+bmp.getHeight()); if(animation_init==animation_up){ canvas.drawBitmap(bmp,bmp_x-animation_up[frame_count]*(bmp.getWidth()/13),bmp_y,p); }elseif(animation_init==animation_down){ canvas.drawBitmap(bmp,bmp_x-animation_down[frame_count]*(bmp.getWidth()/13),bmp_y,p); }elseif(animation_init==animation_left){ canvas.drawBitmap(bmp,bmp_x-animation_left[frame_count]*(bmp.getWidth()/13),bmp_y,p); }elseif(animation_init==animation_right){ canvas.drawBitmap(bmp,bmp_x-animation_right[frame_count]*(bmp.getWidth()/13),bmp_y,p); } canvas.restore();//备注3 sfh.unlockCanvasAndPost(canvas); } publicvoidcycle(){ if(DOWN){ bmp_y+=5; }elseif(UP){ bmp_y-=5; }elseif(LEFT){ bmp_x-=5; }elseif(RIGHT){ bmp_x+=5; } if(DOWN||UP||LEFT||RIGHT){ if(frame_count<2){ frame_count++; }else{ frame_count=0; } } if(DOWN==false&&UP==false&&LEFT==false&&RIGHT==false){ frame_count=0; } } @Override publicbooleanonKeyDown(intkey,KeyEventevent){ if(key==KeyEvent.KEYCODE_DPAD_UP){ if(UP==false){ animation_init=animation_up; } UP=true; }elseif(key==KeyEvent.KEYCODE_DPAD_DOWN){ if(DOWN==false){ animation_init=animation_down; } DOWN=true; }elseif(key==KeyEvent.KEYCODE_DPAD_LEFT){ if(LEFT==false){ animation_init=animation_left; } LEFT=true; }elseif(key==KeyEvent.KEYCODE_DPAD_RIGHT){ if(RIGHT==false){ animation_init=animation_right; } RIGHT=true; } returnsuper.onKeyDown(key,event); } /*(non-Javadoc) *@seeandroid.view.View#onKeyUp(int,android.view.KeyEvent) */ @Override publicbooleanonKeyUp(intkeyCode,KeyEventevent){ if(DOWN){ DOWN=false; }elseif(UP){ UP=false; }elseif(LEFT){ LEFT=false; }elseif(RIGHT){ RIGHT=false; } returnsuper.onKeyUp(keyCode,event); } @Override publicvoidrun(){ //TODOAuto-generatedmethodstub while(true){ draw(); cycle(); try{ Thread.sleep(100); }catch(Exceptionex){ } } } @Override publicvoidsurfaceChanged(SurfaceHolderholder,intformat,intwidth,intheight){ //TODOAuto-generatedmethodstub } @Override publicvoidsurfaceDestroyed(SurfaceHolderholder){ //TODOAuto-generatedmethodstub } } 备注1 此方法是用来响应按键!如果是自己定义一个继承自View的类,重新实现onKeyDown方法后,只有当该View获得焦点时才会调用onKeyDown方法,Actvity中的onKeyDown方法是当所有控件均没有处理该按键事件时,才会调用. 备注2 这里也是对屏幕进行刷屏操作,其实这也只是一种,之前文章里我也用到drawRGB的方法同样实现,当然也可以用fillRect等来刷屏。 那么这里我想说下,在继承view中,因为onDraw方法是系统自动调用的,不像在surfaceview这里这样去在run里面自己去不断调用,在view中我们可以抵用 invalidate()/postInvalidate() 这两种方法实现让系统调用onDraw方法,这里也是和surfaceview中的不同之一! 备注3 这里canvas.save();和canvas.restore();是两个相互匹配出现的,作用是用来保存画布的状态和取出保存的状态的。这里稍微解释一下,当我们对画布进行旋转,缩放,平移等操作的时候其实我们是想对特定的元素进行操作,比如图片,一个矩形等,但是当你用canvas的方法来进行这些操作的时候,其实是对整个画布进行了操作,那么之后在画布上的元素都会受到影响,所以我们在操作之前调用canvas.save()来保存画布当前的状态,当操作之后取出之前保存过的状态,这样就不会对其他的元素进行影响。 对于 canvas.save();和canvas.restore(); 还有不少童鞋不懂,OK、我再补充点: 代码段1: publicvoiddraw(){ Canvascanvas=sfh.lockCanvas(); canvas.drawColor(Color.BLACK); canvas.drawBitmap(bmp1,0,0,paint); canvas.save(); canvas.scale(1.5f,1.5f); canvas.restore(); canvas.drawBitmap(bmp2,0,0,paint); sfh.unlockCanvasAndPost(canvas); } 代码段2: publicvoiddraw(){ Canvascanvas=sfh.lockCanvas(); canvas.drawColor(Color.BLACK); canvas.drawBitmap(bmp1,0,0,paint); canvas.scale(1.5f,1.5f); canvas.drawBitmap(bmp2,0,0,paint); sfh.unlockCanvasAndPost(canvas); } 上面这两个代码片段中我们都假设有两张图片 bmp1和bmp2,并且都画在画布上! 那么代码段1和代码段2的不同: 代码段1中我们进行画布缩放的之前保存了画布状态,做了缩放操作之后又取出之前保存的状态,这样做是为了保证bmp2正常画出来不受到缩放的影响! 代码段2里,画了bmp1后就执行了缩放操作,并且没有保存状态!紧接着画了bmp2,那么bmp2也会一样受到缩放的影响!! 所以我们如果单独处理一张图片的时候,而且不想影响其他部分的绘制,那么应该如下来做: publicvoiddraw(){ Canvascanvas=sfh.lockCanvas(); canvas.drawColor(Color.BLACK); canvas.drawBitmap(bmp1,0,0,paint); canvas.save(); canvas.scale(1.5f,1.5f); canvas.drawBitmap(bmp2,0,0,paint); canvas.restore(); sfh.unlockCanvasAndPost(canvas); } 本文转自 xiaominghimi 51CTO博客,原文链接:http://blog.51cto.com/xiaominghimi/605690,如需转载请自行联系原作者

优秀的个人博客,低调大师

WebAssembly 与 Kubernetes双剑合璧

无处不在的WebAssembly 如果评选2019年编程技术的“网红”,无论是前端圈还是后端圈WebAssembly(WASM) 都绝对能够高票入选。然而,如果评选最被“低估”的技术,我觉得WebAssembly 也可以轻松入围。借用伏尔泰曾评价神圣罗马帝国的句式 “既不神圣,也不罗马,更非帝国”,我们也可以说WebAssembly “既不限于Web,更不是Assembly(汇编语言)”。 在2019年12月,万维网联盟 (World Wide Web Consortium - W3C) 宣布WebAssembly核心规范正式成为Web标准, 这使得 WebAssembly 成为互联网上与 HTML, CSS, and JavaScript并列的第四种官方语言,可以原生的运行在浏览器上。而更加重要的是,WebAssembly 作为一个安全的、可移植、高效率的虚拟机沙箱,可以在 Internet 的任何地方、任何平台(不同操作系统,不同CPU体系架构下)安全运行应用。WebAssembly已得到了所有主流浏览器厂商的广泛支持(Google Chrome, Microsoft Edge, Apple Safari, Mozilla Firefox等),然而它的影响已经远超Web。 WebAssembly的设计初衷之一是为了解决JavaScript的性能问题,使得Web网页应用有接近本机原生应用的性能。作为一个通用、开放、高效的底层虚拟机抽象,众多编程语言(如C/C++, Rust, 等)可以将现有应用编译成为WASM的目标代码,运行在浏览器中 。这让应用开发技术与运行时技术解耦,极大促进了代码复用。 Mozilla在2019年3月推出了 WebAssembly System Interface(WASI),来标准化WebAssembly应用与系统资源的交互抽象,比如文件系统访问,内存管理,网络连接等,类似POSIX这样的标准API。WASI规范大大拓展了WASM应用的场景,可以让其可以超越浏览器环境,作为一个独立的虚拟机运行各种类型的应用。同时,平台开发商可以针对具体的操作系统和运行环境提供WASI接口不同的实现,可以在不同设备和操作系统上运行跨平台的 WebAssembly 应用。这可以让应用执行与具体平台环境实现解耦。这一切使得“Build Once, Run Anywhere”的理想逐渐形成现实。WASI 的示意图如下所示。2019年月,为了进一步推动模块化 WebAssembly 生态系统,Mozilla、Fastly、英特尔和红帽公司携手成立了字节码联盟(Bytecode Alliance),共同领导 WASI 标准、 WebAssembly 运行时、语言工具等工作。 原图:https://hacks.mozilla.org/2019/03/standardizing-wasi-a-webassembly-system-interface/ WASM与容器相爱相杀 WebAssembly是否会取代容器? 正因为 WebAssembly 所具备的的安全、可移植、高效率,轻量化的特点,非常适于应用安全沙箱场景。WASM得到了容器、函数计算、IoT/边缘计算等社区的广泛关注。Docker创始人Solomon Hykes在WASI发布之际的一句Twitter,更是成为了去年容器和WebAssembly社区引用频率最高的一句话之一。 Fastly, Cloudflare等CDN厂商基于WebAssembly技术实现了更加轻量化的应用安全沙箱,可以在一个进程内部运行多个独立的用户应用。阿里云CDN团队EdgeRoutine也实现了类似技术。与容器技术相比,WASM可以实现毫秒级冷启动时间和极低的资源消耗。 原图:https://blog.cloudflare.com/cloud-computing-without-containers/ 当然,世界上没有完美的技术。任何沙箱技术不可能同时满足执行效率、安全隔离性和通用性这三个维度的要求。WASM在安全隔离和通用性等方面与Docker Container等存在差距。虽然如此,我们还是看到了WebAssembly技术巨大的潜力。 WebAssembly容器 我的理解是WebAssmebly可以成为一种容器类型,类似Linux Container或者Windows Container一样。成为一个跨平台的标准应用分发方式和运行时环境。 应用分发 Docker容器的一个重要贡献是其标准化了容器化应用打包规范 Docker Image,而且它已经成为开放容器计划(Open Container Initiative - OCI)的镜像格式标准。Docker镜像提供了自包含、自描述的镜像格式。它可以将应用以及其依赖的环境信息打包在一起,从而实现应用与运行环境解耦,让容器应用可以轻松运行在从本地开发环境到云端生产环境的不同场景中。并且社区围绕Docker镜像构建了繁荣的工具链生态,如Docker Hub可以进行应用分发和CI/CD协同,Nortary/TUF项目可以保障应用可信地分发、交付。 对与WebAssembly,目前社区提供了类似NPM的包管理实现WAPM,可以较好地支持应用的分发。 为WebAssembly应用构建Docker镜像,可以实现双赢的局面。 WebAssembly开发者可以完全复用Docker/OCI镜像规范和工具链,进一步简化应用分发和交付。比如,我们可以将Nginx的WASM镜像作为基础镜像,基于这个镜像可以构建包含不同Web内容的应用镜像;我们可以利用tag对应用版本进行追踪;利用Docker Registry进行应用分发;在这个过程我们还可以进一步利用数字签名来保障安全的软件供应链。 Docker镜像规范支持Multi-Arch镜像,可以简化不同CPU体系架构(如x86, ARM, RISC-V等)的应用镜像的构建与分发。而WebAssembly天生具备可移植性,大大简化了跨平台Docker应用镜像的构建和分发。 参考:利用Docker加速 ARM 容器应用开发和测试流程 我提供了一个技术原型示例项目,https://github.com/denverdino/wasm-container-samples,大家可以参考其中的例子来构建WASM容器镜像。由于WebAssembly应用采用紧凑的二进制格式,而且没有任何操作系统依赖,WASM应用可以构建出非常小的容器镜像。大家可以自行感受一下: $ sudo ctr image ls REF TYPE DIGEST SIZE PLATFORMS LABELS docker.io/denverdino/c-http-server-wasm:latest application/vnd.docker.distribution.manifest.v2+json sha256:2efa759f46f901cda2e6a9b4228c423b17a960c06e957964e72c21dc5b42408f 29.2 KiB linux/amd64 - docker.io/denverdino/hellowasm:latest application/vnd.docker.distribution.manifest.v2+json sha256:cadcc8b07eb82b18db2c8f500fa2b11e5ebf2e9054cfa687e4ffe44861860132 8.2 KiB linux/amd64 - docker.io/denverdino/nginxwasm:latest application/vnd.docker.distribution.manifest.v2+json sha256:8735c82524a463b842b7c79f2c1be8094ee1c57cfd34154f68752fbe79c25998 582.7 KiB linux/amd64 - 安全隔离 WebAssembly的最初设计目标是让应用可以安全运行在浏览器中。WASM虚拟机提供的的沙箱和内存隔离机制,可以有效减少安全攻击面。而当WebAssembly走出浏览器,面向更加通用的场景。WASM也面对更加复杂的安全挑战。 WASI 提供了基于能力的安全模型。WASI应用遵循最小权限原则,应用只能访问其执行所需的确切资源。传统上,如果应用需要打开文件,它会带路径名字符串调用系统操作open。然后系统调用会检查应用是否具有访问该文件的相关权限,比如Linux实现了基于用户/组的权限模型。这样隐式的安全模型,依赖于正确的安全管理配置,比如一旦特权用户执行了一个恶意应用,它就可以访问系统中任意的资源。而对于WASI应用而言,如果它需要需要访问指定文件等系统资源,需要从外部显式传入加有权限的文件描述符引用,而不能访问任何其他未授权资源。这中依赖注入的方式可以避免传统安全模型的潜在风险。一个示意图如下 原图:https://hacks.mozilla.org/2019/03/standardizing-wasi-a-webassembly-system-interface/ 我们可以看到WASI的安全模型与传统操作系统安全模型非常不同,而且还在持续演进中。比如字节码联盟提出了 nanoprocess 来解决应用模块间的安全协同和信任传递。 WebAssembly/WASI的安全模型依然存在不足,比如 资源隔离: 对于内存资源,WebAssembly实现了线性内存模型。WebAssembly应用只能利用索引访问传入的一段逻辑线性内存。而WASM虚拟机负责确定内存的实际物理地址,WASM应用无法获知内存的真实地址,也无法通过越界访问等方式发动攻击。所以理论上,可以对WASM应用进行资源容量限制。但是目前部分WASM虚拟机还无法对内存进行精确的隔离限制 对于CPU资源,部分的WASM虚拟机实现可以对应用使用的CPU资源进行计量,但是大多无法实现精确的配额限制、优先级和抢占式调度。 I/O资源,比如IOPS等,WASM目前完全没有相关的隔离能力。 网络安全: WASI的Capability模型对于文件系统访问相对比较容易保护。但是这个静态的安全模型无法适用于动态的网络应用场景。在微服务架构中,应用经常通过Service Registry进行服务发现,为服务的调用者和提供者实现动态的调用绑定。这个语义是无法用静态的capability模型描述和注入的。这也导致了WASI的网络部分API还处于讨论之中。现有的WASI网络安全模型,以及相关讨论, Linux操作系统和容器技术已经提供了非常完备的资源隔离和安全隔离实现。与WebAssembly结合在一起可以应对不同场景对不同隔离级别的需求。 共享进程资源 - 多个WASM应用模块运行在一个WASM虚拟机进程内部,依赖WASM运行时进行隔离。隔离级别低,控制粒度比较粗,资源开销极小。可以以较小代价保障系统安全。适合受限问题域的应用安全隔离。 独立进程资源- 不同WASM应用模块运行在不同的WASM虚拟机进程中,可以复用操作系统的进程级隔离能力,比如CGroup。此外,还可以利用类似Kubernetes中的Network Policy (网络策略),或者服务网格(如Istio)等技术,对进程的网络访问进行细粒度的控制,甚至实现零信任网络。隔离级别比较高,控制粒度比较细,资源开销适中。可以应用于更加通用的场景。 注:当然利用安全沙箱如虚拟化等技术,结合WebAssembly,可以进一步最小化安全攻击面,但是ROI不高。 调度与编排 在云时代,Kubernetes已经成为分布式环境下资源调度和应用编排的事实标准。Kubernetes可以屏蔽底层设施的差异性。可以在同一个K8s集群中包含x86、ARM等不同体系架构的节点,可以支持Linux,Windows等不同的操作系统。Kubernetes和WebAssembly相结合可以进一步提升应用的可移植性。 微软的Deis Labs年初发布了一个实验项目,https://github.com/deislabs/krustlet来利用 Virtual Kubelet类似的架构调度 WebAssembly 应用。但是这个方式有很多局限,无法借助容器方式进行应用分发,也无法利用K8s 的语义进行资源编排。 难得有一个春节假期可以宅在家里间,我基于Derek McGowan去年的一个实验性项目https://github.com/dmcgowan/containerd-wasm,完善了containerd的WASM shim实现。可以让containerd支持WASM container,并且可以利用Kubernetes集群管理和调度 WASM container。项目的代码实现:https://github.com/denverdino/containerd-wasm 注:这个项目更多是概念验证,进程管理、资源限制,性能优化等的细节并没未完整实现。 整个系统的架构设计如下,“container-shim-wasm-v1”做为Containerd的扩展,利用 wasmer 作为WASM应用运行时环境,可以实现与runc容器一致的用户体验。 我们还会将其注册为 K8s 的一个RuntimeClass ,允许用户利用K8s来交付和运维WASM应用。 注:RuntimeClass是 Kubernetes v1.12 引入的新概念,可以让Kubernetes支持多种不同的容器运行时,比如 runc容器、或者Kata Containers,gVisor等安全沙箱容器。更多细节可以参考,containerd与安全沙箱的Kubernetes初体验 Talk is Cheap, 放码过来 首先,我们将利用Minikube创建一个K8s测试环境,并将 Containerd 作为Kubernetes集群的容器运行时。 创建虚拟机测试环境 创建Minikube K8s集群,并将 Containerd 作为Kubernetes集群容器运行时 minikube start --image-mirror-country cn \ --iso-url=https://kubernetes.oss-cn-hangzhou.aliyuncs.com/minikube/iso/minikube-v1.6.0.iso \ --registry-mirror=https://tgtsuwdg.mirror.aliyuncs.com \ --container-runtime=containerd 进入 Minikube 虚拟机 $ minikube ssh _ _ _ _ ( ) ( ) ___ ___ (_) ___ (_)| |/') _ _ | |_ __ /' _ ` _ `\| |/' _ `\| || , < ( ) ( )| '_`\ /'__`\ | ( ) ( ) || || ( ) || || |\`\ | (_) || |_) )( ___/ (_) (_) (_)(_)(_) (_)(_)(_) (_)`\___/'(_,__/'`\____) 配置环境所需依赖 wasmer 0.13 minikube缺省安装了container 1.2.x,需要升级 containerd 1.3.x 我提供了一个预编译的 containerd-wasm-shim-v1,也可自己编译一个版本。 cd ~ # Install Wasmer 0.13.1 curl -L -O https://github.com/wasmerio/wasmer/releases/download/0.13.1/wasmer-linux-amd64.tar.gz gunzip wasmer-linux-amd64.tar.gz tar xvf wasmer-linux-amd64.tar sudo cp bin/* /usr/bin/ # Upgrade containerd to v1.3.2 curl -L -O https://github.com/containerd/containerd/releases/download/v1.3.2/containerd-1.3.2.linux-amd64.tar.gz gunzip containerd-1.3.2.linux-amd64.tar.gz tar xvf containerd-1.3.2.linux-amd64.tar sudo systemctl stop containerd sudo cp bin/* /usr/bin/ sudo systemctl restart containerd # Install containerd-wasm-shim wget http://kubernetes.oss-cn-hangzhou.aliyuncs.com/containerd-wasm/containerd-shim-wasm-v1 chmod +x containerd-shim-wasm-v1 sudo mv containerd-shim-wasm-v1 /usr/bin/ 配置 containerd 支持 WASM shim 在containerd配置文件中添加 wasm shim相关配置,并重启containerd。 $ cat <<EOF | sudo tee -a /etc/containerd/config.toml disabled_plugins = ["restart"] [plugins.cri.containerd.runtimes.wasm] runtime_type = "io.containerd.wasm.v1" EOF $ sudo systemctl restart containerd 测试 Hello World WASM容器应用 $ sudo ctr image pull docker.io/denverdino/hellowasm:latest docker.io/denverdino/hellowasm:latest: resolved |++++++++++++++++++++++++++++++++++++++| manifest-sha256:cadcc8b07eb82b18db2c8f500fa2b11e5ebf2e9054cfa687e4ffe44861860132: done |++++++++++++++++++++++++++++++++++++++| layer-sha256:ecda28441283ecf01d35bca0361f2c1ef26a203454a06789ee5ce71ba1e32ca3: done |++++++++++++++++++++++++++++++++++++++| config-sha256:57974480d640c8d60d254a8b0fa4606b2c7107fe169bc3ddd455091277c3a5e4: done |++++++++++++++++++++++++++++++++++++++| elapsed: 3.0 s total: 0.0 B (0.0 B/s) unpacking linux/amd64 sha256:cadcc8b07eb82b18db2c8f500fa2b11e5ebf2e9054cfa687e4ffe44861860132... done $ sudo ctr run --rm --runtime io.containerd.wasm.v1 docker.io/denverdino/hellowasm:latest test1 Hello world 测试 Nginx的WASM容器应用 $ sudo ctr image pull docker.io/denverdino/nginxwasm:latest docker.io/denverdino/nginxwasm:latest: resolved |++++++++++++++++++++++++++++++++++++++| manifest-sha256:8735c82524a463b842b7c79f2c1be8094ee1c57cfd34154f68752fbe79c25998: exists |++++++++++++++++++++++++++++++++++++++| layer-sha256:27f4d8ad067fbb709d18ea5acd7a5ddfb85851e5d9f030636e9da3d16cc4bd07: done |++++++++++++++++++++++++++++++++++++++| config-sha256:a55bd3bdb9d00fdac5ee2f64bfc1856e58e8bb90587943969ad3d8115f4ced70: done |++++++++++++++++++++++++++++++++++++++| elapsed: 3.0 s total: 0.0 B (0.0 B/s) unpacking linux/amd64 sha256:8735c82524a463b842b7c79f2c1be8094ee1c57cfd34154f68752fbe79c25998... done $ sudo ctr run --rm --runtime io.containerd.wasm.v1 docker.io/denverdino/nginxwasm:latest test2 2020/02/01 07:01:21 [notice] 30672#0: using the "select" event method 2020/02/01 07:01:21 [notice] 30672#0: nginx/1.15.3 2020/02/01 07:01:21 [notice] 30672#0: built by clang 6.0.1 (emscripten 1.38.11 : 1.38.11) 2020/02/01 07:01:21 [notice] 30672#0: OS: Linux 4.19.81 2020/02/01 07:01:21 [notice] 30672#0: getrlimit(RLIMIT_NOFILE): 1024:1024 在 Minikube 外部,可以用如下方式获得 nginx 应用的访问地址 $ echo http://$(minikube ip):8080 http://192.168.64.13:8080 利用浏览器打开上述地址,显示如下 创建WASM容器的RuntimeClass CRD 为了将WASM容器可以被Kubernetes所调度,我们需要创建一个RuntimeClass CRD 下载示例文件 $ git clone https://github.com/denverdino/wasm-container-samples $ cd wasm-container-samples 注册 RuntimeClass “wasm”,这个值 $ cat wasm-runtimeclass.yaml apiVersion: node.k8s.io/v1beta1 kind: RuntimeClass metadata: name: wasm handler: wasm $ kubectl apply -f wasm-runtimeclass.yaml runtimeclass.node.k8s.io/wasm created $ kubectl get runtimeclass kubectl get runtimeclass NAME CREATED AT wasm 2020-02-01T06:24:12Z 在K8s中运行WASM容器应用 在K8s应用的yaml manifest中,我们可以在Pod Spec上指明所需 runtimeClassName。下面我们就用K8s来部署一个nginx的WASM容器。 $ cat nginx-wasm.yaml apiVersion: v1 kind: Pod metadata: name: nginx-wasm spec: runtimeClassName: wasm containers: - name: nginx image: denverdino/nginxwasm ports: - containerPort: 8080 $ kubectl apply -f nginx-wasm.yaml pod/nginx-wasm created $ kubectl get pod NAME READY STATUS RESTARTS AGE nginx-wasm 1/1 Running 0 9s 新机遇、新希望 目前为止,WebAssembly 技术仍处于初期阶段,WASI也有很多局限性。但是社区的进展非常快,SIMD 指令支持,多线程处理等规范也正在快速演进中。WebAssembly已经打破次元壁,将高性能的计算能力带领到Web浏览器端,越来越多的计算密集型的游戏、AI模型预测、和数据处理应用被移植到浏览器端,可以为应用提供更加优化的用户体验。 WebAssembly更广阔的空间在云计算领域、区块链等分布式计算领域。WebAssembly 轻量、敏捷、安全的特性,可以有效降低Serverless应用启动速度和资源消耗。同时WebAssembly的可移植,可以让应用一致运行在从云端服务器到边缘IoT设备等不同平台环境中,让计算无处不在。 利用containerd的扩展机制,可以为WebAssembly应用提供与其他容器应用一致的、抽象的、应用分发、交付和运维模型,可以在Kubernetes集群中进行统一调度和管理。希望通过类似的探索可以简化基于WebAssembly的分布式应用管理和运维。 后记 本文写在2020年的春节期间,这个春节注定将会被所有人铭记。众志成城,抗击疫情!天佑中华,武汉加油!

优秀的个人博客,低调大师

北京经开区信产局指导、爱分析联合主办,问学极客行走进亦庄

9 月 16 日,神州问学发起的城市巡回技术沙龙"问学极客行"走进北京亦庄·模数 OPC 社区。本次活动由北京经济技术开发区信息技术产业局指导,神州问学主办,爱分析、WaytoAGI 模数 OPC 社区联合主办,神州数码通明湖研究院提供智库支持。本次活动聚焦"Agent 如何接进企业系统、跑通真实任务"这一核心命题,以主题分享与圆桌对话两种形式展开。

资源下载

更多资源
腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册