在电子工程世界为您找到如下关于“服务器”的新闻
服务器资料下载
黑客任务实战服务器攻防篇网站服务器的黑客攻防一直是网络安全中最重要的一部分。本书作者在经过数月的努力之后,终于将网站服务器的黑客攻防以深入浅出、简单易懂的方式呈现在您的眼前,让您不必具有高深的网络知识和经验,只要依照本书的操作说明来按图索骥的进行,就可以完成许多看似不能的黑客任务,让您充分了解与感受到黑客高手的技巧和行为,如此网管人员才可对症下药,防止黑客的入侵与破坏。 本书中详细的讨论了...
的分布设计;第三章至第七章是研究分布式数据库系统的重点,分别讨论分布式数据库的查询处理与优化、事务管理、并发控制、可靠性、安全性以及分布式数据库的目录管理等;第八章从理论和实际应用角度,阐述了客户机/服务器计算模式的概念、结构特征、工作原理、技术方法等,及与分布式数据库系统的关系;第九章以流行的数据库管理系统SYBASE为例,介绍SYBASEDBMS的功能和性能特点、体系结构及相应成分,系统建模和...
DNS服务器及其配置:DNS的作用将主机名字转换成二进制IP地址。1.DNS被设计成为一个联机分布数据库系统。2.DNS采用客户服务器模式。3.DNS由若干个域名服务器组成不是一台。①.大多数域名的转换都是在本地映射。②少数域名在Internet 网上通信映射。DNS的工作原理当客户机需要访问Internet上某一主机时,首先向本地DNS服务器查询对方IP地址,往往本地DNS服务器继续向另外一台...
;111.5.1&& 关于运行DOS/Windows上的&&&&& 程序&111.5.2&& 关于Linux的资料来源&121.5.3&& 关于获取帮助&13第2章&& 服务器平台***和设备管理&152.1&& 硬件选择...
随着嵌入式技术和网络技术的发展,通过嵌入Web服务器来管理和控制设备成为嵌入式设备管理的一种发展趋势。越来越多的嵌入式系统将Web服务器引入其中,可方便有效地管理这些挂接在网络上的嵌入式设备,用户可以使用浏览器通过互联网来控制它们。本文所设计的嵌入式Web服务器就是基于HTTP协议和TCP/IP协议上的一种界面友好的Web服务器。 本文首先介绍了嵌入式Web系统的基本概念、历史和发展状况,同时...
采集的数据放在服务器中供用户使用。1.2 虚拟仪器网络测试系统设计虚拟仪器网络测试系统的设计需从虚拟仪器和网络技术两方面考虑。1.2.1虚拟仪器部分分析测试系统的要求和系统的功能,根据系统功能的要求,在软件和硬件之间进行优化选择,从而确定仪器所必需的硬件模块,以便用最少的模块实现仪器的最佳功能。根据应用情况与实际的条件选择基于计算机的虚拟仪器的仪器模块(VXI总线、PCI总线、PXI总线、GPIB...
1.1 活动目录的域层次结构1.2 活动目录的域名1.2.1 DNS命名约定1.2.2 NetBIOS域名1.3 活动目录和DNS1.3.1 DNS层次和活动目录1.3.2 DNS和Internet1.3.3 活动目录和Internet1.3.4 DNS主机名和Windows 2000计算机名1.3.5 DNS名字服务器和区域1.3.6 与活动目录相结合的DNS1.3.7 对动态更新的支持1.4...
服务器,也称伺服器,是提供计算服务的设备。由于服务器需要响应服务请求,并进行处理,因此一般来说服务器应具备承担服务并且保障服务的能力。
服务器的构成包括处理器、硬盘、内存、系统总线等,和通用的计算机架构类似,但是由于需要提供高可靠的服务,因此在处理能力、稳定性、可靠性、安全性、可扩展性、可管理性等方面要求较高。
在网络环境下,根据服务器提供的服务类型不同,分为文件服务器,数据库服务器...
近年来,随着嵌入式系统的快速发展,越来越多的嵌入式设备被用于工业控制、智能家居等领域。同时伴随着网络技术的发展,嵌入式设备通过网络接入局域网或者Internet已经逐步成为发展的趋势。通过在嵌入式设备中内置Web服务器,用户可以在任何一台联网的计算机上通过浏览器来获取设备的信息,用户还可以通过网络对设备进行配置和管理。因此研究和开发嵌入式Web服务器具有重要的实际意义和应用价值。 本文在...
优秀硕士论文《网络游戏服务器集群的设计和实现》,本论文立足于网络游戏服务器端的开发,在借鉴前人设计的基础上,将网络游戏服务中所普遍需要的几大功能进行***、实现并进一步将它们构建为服务器集群。对“如何稳定地协调游戏服务器与各功能服务器并同时给游戏玩家以较完美的游戏体验?如何利用服务器集群来将维持整个虚拟游戏世界运转的任务分配到不同的计算机?如何达到降低单台计算机的负载,更好的保证网络的稳定性和通讯...
服务器相关帖子
附近的人功能/摇一摇功能/第三方h5接入功能/
app支持红包发送/转账功能/AA收款功能/收藏功能/发送地理位置功能/阅后即焚功能/发送文件功能/发送图片功能/发送视频功能
app支持我的钱包功能/充值/提现/在线升级功能/帮助反馈功能
完备的后台管理模块/权限化的后台管理分配/
服务器支持分布式部署集群/支持redis缓存分布式/支持文件分布式/支持数据库分布式/
app经过第三方听云...
与原有的14纳米FinFET相比,全新的7LP技术将提升40%的性能
格芯今日宣布推出其具有7纳米领先性能的(7LP)FinFET半导体技术,其40%的跨越式性能提升将满足诸如高端移动处理器、云服务器和网络基础设施等应用的需求。设计套件现已就绪,基于7LP技术的第一批客户产品预计于2018年上半年推出,并将于2018年下半年实现量产。
2016年9月,格芯曾宣布将充分利用其在高性能...
对互动加强而提出的新要求。从目前市场来看,低功耗、高性能的美颜功能是行业趋势,很多直播云服务商如阿里云、星域CDN等,都已添加这些功能。3、推流直播内容采集、处理好之后,还要上传到服务器,通过CDN进行分发,才能向用户播放,这就是推流。推流有回源、直推、转推等多种形式,各有优点。优质的直播系统源码搭建出的直播平台不仅受人们的喜爱,而且还能在源码的基础上进行二次开发,发挥您的想象,实现更多的功能。不...
芯片到服务供应链上建立持续的信任性。厂商还能确保连网设备是在受信任的路径上,运行制造商所***的正确软件,并在其设定的状态中运作。在此基础上,服务器能够信任试图访问其服务的设备,而设备也能信任它所访问的是正确的服务。
此展示采用了Imagination支持OmniShield?技术的MIPS CPU以及 Intercede功能强大的MyTAM?解决方案,再加上重要合作伙伴的技术,共同展现了创新的...
。 消防联动报警。子母机与单体机双用:可组成子母机。只需要对母机进行信息管理。子母可直接使用。实现防反潜,出入门控制等复杂门禁控制。也可单独使用。多种通讯方式并用:RS485 USB U盘 TCP/IP 与广域网服务器方式 与设备进行连接,简单方便。实时监控:通过TCP/IP 或 广域网服务器方式 ,实现对设备的门状态进行实时监控,并且实时采集出入记录。广域网服务器方式连接:独创的一种新型TCP/IP...
围绕该案件,阿里云作为云服务器提供商,究竟有没有“共同侵权”,又该不该审查客户信息,成为法律相关人士、科技界人士以及社会舆论探讨的焦点。
有律师界人士认为,阿里云在被告知有侵权内容时并未积极回应,也未告知侵权方,由于提供技术支持且未在短时间内迅速采取一定措施,应该承担连带责任。
但华东政法大学教授王迁举例认为,服务器提供商类似于酒店式公寓的管理者,公寓管理者虽然都会保留一把房间...
产品简介: “大棚监测一体化采集器”是我们开发的用于服务于设施农业温室大棚内实时监测棚内温度、湿度、光照、土壤温度、土壤湿度的设备。主要包括硬件终端(环境采集设备),云端服务管理软件,手机客户端等几部分。终端设备可以采集环境因子并在超标情况下发送预警信息,同将数据传输至云端服务器。服务器会将环境数据与生产相关数据相结合,用于数据挖掘与统计分析,进而将相关服务信息推送至用户手机客户端。同时用户...
11个黑色方盒子被装在一台一人多高的机柜里,身后连着密密麻麻的电线、网线,设备嗡嗡作响,信号灯不停闪烁,旁边两台空调正在抓紧工作。如果室温超过25摄氏度,这11台服务器将可能宕机。
这是6月7日傍晚,发生在成都高新区一个创业园区内的场景。“准星数学高考机器人”AI-Maths在这里迎来了属于它的2017年文科数学“高考”。
这是人工智能向人类发起的最新一场挑战。此前,谷歌公司旗下...
技术常用在大于等于200MHz振荡器。SAW优势就是可支持GHz以上应用;缺点是局限于±50ppm频率稳定度、老化率第一年超过±10ppm和大尺寸封装(7050)等因素。
一张图看懂MEMS差分振荡器
MEMS差分振荡器的优势和规格SiT9121和SiT9122系列MEMS振荡器定位于高性能电信、存储和网络应用,如核心和边缘路由器,SATA、SAS、光纤通道主机总线适配器,云存储、服务器、无线...
识别等,研发的以自动解题技术为核心的人工智能系统。当天考试前,专家组通过技术验证确认其在完全掐断题库、断网、无人干涉、仅有12台服务器的情况下进行考试。18:28分,工作人员将北京文科数学卷作为首套考题录入系统,仅22分钟后AI-MATHS完成答卷,成绩为105分;随后全国通用卷二卷再次录入,系统仅10分钟完成,成绩为100分。
“丢分主要在应用题,可能它不明白题目的意义。”三位评卷人之一的成都...
服务器视频
服务器创意
你可能感兴趣的标签
热门资源推荐一种对函数运行进行跟踪的移动终端、服务器和方法
专利名称一种对函数运行进行跟踪的移动终端、服务器和方法
技术领域本发明涉及移动通信监测技术,特别是指一种对函数运行进行跟踪的移动 终端、服务器和方法。
背景技术近年来随着通信技术的不断发展,移动终端的功能和通信运营商所提供的 业务服务不断增加,而用户对于移动终端的多功能性、实用性、质量以及对于
业务服务的要求也越来越高;同时,由于移动终端的研发测试周期不断减少, 以及运营商提供的业务越来越繁多,因此导致移动终端本身,以及移动终端在 进行业务服务的过程中所出现的问题逐渐增多,而如何对所出现的问题进行跟 踪定位和处理,或者给出处理建议也变得越来越困难,即使有的现有技术中提 出了对移动终端的函数调用进行跟踪的具体方法,也都是在源代码文件中设置 跟踪函数,大量得记录函数的调用,甚至记录其它变量来对出现的异常和故障 进行定位,然后再把代码文件编译成目标机器码运行,极大的浪费了移动终端 有限的资源并影响了移动终端的运行速度。
本发明的目的是提供一种对函数运行进行跟踪的移动终端、服务器和方 法,用于解决现有技术中,需要对大量的函数调用甚至变量进行记录,导致占 用移动终端过多资源,影响运行速度的缺陷。
一种对函数运行进行跟踪的移动终端,移动终端包括指令模块、数据处理 模块和诊断引擎模块;所述数据处理模块用于执行移动终端的业务功能,分布 形式设置或插入在源程序的预定位置;所述指令模块设置在所述数据处理模块 的预定位置,用于跟踪所述数据处理模块中调用函数的运行信息;诊断引擎模 块包括函数进入模块及函数退出模块,用于发送所述运行信息。
一种对函数运行进行跟踪的方法,移动终端运行之后,开始调用函数之后 如果遇到指令,则该指令记录此时的返回地址,并跟踪所述数据处理模块中调
4用函数的运行信息,并在终止对所述运行信息的跟踪之后继续按照原有顺序执 行后续函数。
应用本发明提供的技术方案,使得在移动终端的运行过程中,不再需要对 调用函数的过程进行大量的跟踪记录,节省了所占用的移动终端的资源,而且 不会降低移动终端原有的运行速度。
图1为本发明实施例的数据处理模块、指令模块和函数进入/退出模块之
间的结构示意图2为本发明实施例服务器与移动终端之间通信方式示意图3为本发明实施例的移动终端结构示意图4为本发明实施例的服务器结构示意图。
具体实施例方式
为使本发明的目的、技术特征和实施效果更加清楚,下面将结合附图及具 体实施例对本发明的技术方案进行详细描述。
如图l所示,箭头方向表示移动终端执行或调用函数的过程中,在程序中 的运行以及跳转方向;源程序是移动终端中用于管理移动终端的程序,通常是 指移动终端的系统级程序,例如操作系统;数据处理模块101则是用于完成具 体功能的模块,通常是若干个用于实现不同功能的程序,也可以是其它插件或 者驱动等程序。图中的指令模块102用于调用源程序中不同的数据处理模块 101,且指令模块102包括两个子模块函数进入模块103和函数退出模块104, 当指令模块102调用数据处理模块101时,函数进入模块103位于指令模块 102中保存函数返回地址的指令之后被执行,函数退出模块104则通常位于指 令模块102中用于调用函数的指令之后被执行。
为了清楚完整的揭示移动终端的内部结构和工作原理,如图3所示,是移 动终端的结构示意图,不仅包括数据处理模块101,还包括了指令模块102和 诊断引擎模块105。其中
诊断引擎模块105,用于记录并发送移动终端在工作过程中所跟踪的运行 信息;在跟踪调用函数或调整调用函数的过程中,诊断引擎模块105可以将其 中所跟踪或者调整的运行信息记录下来,并发送给远端的服务器,由制造商或者运营商进行分析,如图2所示,通常是以空中接口技术(OTA, Over-the-Air Technology)来实现,当然不排除使用其它技术的可能;下面以常用的OTA技 术为例进行描述,如图2所示,服务器通过空中接口技术OTA向位于移动终 端的诊断引擎模块105发送指令,请求诊断引擎模块105发送所述运行信息, 诊断引擎模块105根据该指令进行发送运行信息。所述OTA是通过空中接口 对用户识别模块(SIM, Subscriber Identity Module)卡数据及应用进行远程管理 的技术,空中接口可以采用无线应用协议(WAP, Wireless Application Protocol), 通用分组无线业务(GPRS, General Packet Radio Service)、码分多址接入 1 X(CDMA IX, Code Division Multiple Access 1 X)及短消息技术。
指令模块102位于数据处理模块101的预定位置,作为一个指令容器,用 于存放来自服务器的具体指令;所述预定位置通常是由制造商或者运营商所关 心的问题所可能出现的位置来决定,例如如果关心的问题是关于调用特定函数 以及推出特定函数时的状态,则该预定位置就是该特定函数之前或者之后的位 置;所述指令可以是两条指令,或者是一条指令,或者是其它方式的指令。
函数进入模块103和函数退出模块104是所述指令模块102的子模块,其
函数进入模块103通常位于指令模块102中保存函数返回地址的指令之 后,用于记录调用数据处理模块101的函数时应当记录下来的返回地址,甚至 寄存器状态,变量赋值等数据。
函数退出模块104通常位于指令模块102中调用函数的指令之后,用于记 录退出数据处理模块101的调用函数时的相应的各种数据。
当所述指令模块102包括两条指令时,具体包括第一指令用于保存函数 的返回地址;第二指令用于调用函数。
移动终端运行并开始调用函数之后,首先进入数据处理模块101,当执行 并遇到所述指令模块102,该指令模块102执行第一指令,第一指令此时至少 要记录返回地址;通常是将该返回地址记录在对应的堆栈中,也可以记录在其 它类型的变量或者是数据结构中。执行完第一指令后,所述指令模块102执行 第二指令,第二指令此时调用函数运行,所述函数执行特定特定的任务。在第 二指令调用函数之后,移动终端继续运行,并由函数进入模块103记录调用函数的时刻,以及此时相应的变量、寄存器等的赋值,并设定将要完成的任务 或者事件等等。在调用函数执行完毕并满足了退出该调用函数的条件时,由函
数退出模块104记录预先设定的所需要记录的事件、寄存器以及其它变量等。 所述函数退出模块104与函数进入模块103既可以嵌入所述指令模块 102,还可以是单独的一个模块,如果是单独的模块则可以位于数据处理模块 IOI的某个位置,该位置通常是指令模块102之前或者之后,或者是所调用函 数之前或者之后;并在所调用的函数中还可以通过引用这两个模块实现相应的 记录功能。
在函数退出模块104执行完毕之后,退出调用函数的同时,取出第一指令 所存放的返回地址按照该地址并返回;之后,按照数据处理模块101原有的顺 序执行后续操作。
以上描述了所述指令模块102存有两条指令(即第一指令、第二指令)时, 跟踪调用函数的优选实施例;当所述指令模块102仅仅存有一条指令时,为了 称谓方便,称作唯一指令,唯一指令实际是一个软中断,其优选实施例描述如 下
移动终端运行并开始调用函数之后,首先进入数据处理模块101,如果在 运行时遇到指令模块102,该指令模块102执行唯一指令,唯一指令用于保存 返回地址,并且实现软中断来进入操作系统的内核。
与两条指令相同的是,可以在数据处理模块101所调用函数的开头放置一 个函数进入模块103,该函数进入模块103可以是单独的一个模块,也可以嵌 入到指令模块102中,函数进入模块103记录进入函数的时刻,以及此时相应 的变量、寄存器等的赋值,并设定将要完成的任务或者事件等等;
还可以进一步提供一个函数退出模块104,该模块可以是单独的一个模 块,也可以嵌入到指令模块102中,执行完上述调用的函数之后会遇到该函数 退出模块104,该模块记录预先设定所需要记录的事件、寄存器以及其它变量。
为了进一步增加对移动终端调用函数的跟踪功能,甚至控制移动终端的运 行,本发明实施例进一步在移动终端提供了一个调整模块106,该模块可以位 于指令模块102内部,并用于在所述指令模块102的控制范围内,实现对数据 处理模块101所实现的功能进行调整、修正等。例如,当数据处理模块101完成函数A之后顺序执行函数B时,可以由调整模块106决定不再执行函数 B,而是在函数A执行完之后直接跳转到函数C的入口处;调整模块106还可 以用于改进数据处理模块101的执行效率,例如可以在所调用的函数中引入一 个新的算法或者是功能。总之,调整模块106可以灵活应用,而不应当局限于 上述提出的各种具体功能。调整模块106也可以是单独的一个模块,在所调用 的函数中可以通过引用该调整模块106实现相应的调整功能;也可以是嵌入在 指令模块102中,可以通过在所调用的函数中设定针对调整模块106的地址或 者其它方式实现对该模块的引用。
本发明实施例还提供了 一种对函数运行进行跟踪的服务器,如图4所示, 包括收发模块201、异常及故障诊断模块202、异常及故障管理模块203。
收发模块201用于接收来自移动终端的诊断引擎模块105的运行信息,并 发送给所述异常及故障诊断模块202;
异常及故障诊断模块202用于根据所述运行信息对业务异常和设备故障 信息进行分析,并可以进一步给出解决上述异常和故障的建议;
异常及故障管理模块203用于接收来自所述收发模块201的标识业务异常 和设备故障信息,并根据该标识通过收发模块201发送指令到移动终端获取所 述运行信息。
服务器进一步包括一个异常及故障判断模块204,该模块接收来自所述收 发模块201的运行信息;异常及故障判断模块204用于判断出现的所述运行信 息的类型;所述类型至少包括内部故障、外部故障。其中,内部故障至少包 括死机、死屏;外部故障至少包括网络信号没有达到预定强度等。
应用本发明提供的优选实施例,使得在移动终端的运行过程中,不再需要 对调用函数的过程进行大量的跟踪记录,节省了所占用移动终端的资源,而且 不会降低移动终端原有的运行速度,并可以为制造商和运营商提供调用函数的 记录进行分析。
应当说明的是,以上实施例仅用以说明本发明的技术方案而非限制,所有 的参数取值可以根据实际情况调整,且在该权利保护范围内。本领域的普通技 术人员应当理解,可以对本发明的技术方案进行修改或者等同替换,而不脱离 本发明技术方案的精神范围,其均应涵盖在本发明的权利要求范围当中。
1.一种对函数运行进行跟踪的移动终端,其特征在于,移动终端包括指令模块、数据处理模块和诊断引擎模块;所述数据处理模块用于执行移动终端的业务功能,分布形式设置或插入在源程序的预定位置;所述指令模块设置在所述数据处理模块的预定位置,用于跟踪所述数据处理模块中调用函数的运行信息;诊断引擎模块包括函数进入模块及函数退出模块,用于发送所述运行信息。
2. 根据权利要求1所述的移动终端,其特征在于,当所述移动终端执行 业务功能时,所述源程序中数据处理模块编译为汇编代码,并在该数据处理模 块被调用时,执行所述指令模块中的跳转指令。
3. 根据权利要求1所述的移动终端,其特征在于,所述指令模块进一步 包括两条指令第一指令用于保存所述源程序中数据处理模块调用函数的返回地址; 第二指令用于调用函数。
4. 根据权利要求3所述的移动终端,其特征在于,所述指令模块进一步 包括一个函数进入模块和函数退出模块;所述函数进入模块位于所述第一指令之后,用于记录进入数据处理模块的 函数时应当记录的返回地址、寄存器状态、变量赋值和事件信息;所述函数退出模块位于所述第二指令之后,用于记录退出数据处理模块的 函数时应当记录的寄存器状态、变量赋值和事件信息。
5. 根据权利要求1所述的移动终端,其特征在于,所述指令模块进一步包括一条唯一指令所述唯一指令用于保存返回地址,并且切入操作系统的内核。
6. 根据权利要求1所述的移动终端,其特征在于,所述指令模块进一步 包括一个调整模块;所述调整模块用于在所述指令模块调用函数的过程中,实现对数据处理模块所实现的原有功能或者结束条件进行操作。
7. —种对函数运行进行跟踪的方法,移动终端运行之后,其特征在于,开始调用函数之后如果遇到指令,则该指令记录此时的返回地址,并跟踪所述源程序中数据处理模块调用函数的运行信息;在终止对所述运行信息的跟踪之 后发送所述运行信息并继续按照原有顺序执行后续函数。
8. 根据权利要求7所述的方法,其特征在于,如果所述指令为两条指令, 则在第一指令保存所述源程序中数据处理模块调用函数的返回地址之后,执行 第二指令来调用所述调用函数。
9. 根据权利要求8所述的方法,其特征在于,保存所述返回地址之后, 进一步包括,记录进入所述调用时应当记录的返回地址、寄存器状态、变量赋 值和事件信息;并在调用所述调用函数之后,记录退出该调用函数时应当记录的寄存器状 态、变量赋值和事件信息。
10. 根据权利要求8所述的方法,其特征在于,在调用所述调用函数之后, 还包括在所述调用函数运行的过程中,对源程序中数据处理模块所实现的原有 功能或者结束条件进行操作。
11. 一种对函数运行进行跟踪的服务器,其特征在于,该服务器包括收发 模块、异常及故障诊断模块、异常及故障管理模块;所述收发模块用于接收来自移动终端的运行信息; 所述异常及故障诊断模块用于根据所述运行信息对所述业务异常和设备故障信息进行分析;所述异常及故障管理模块用于标识业务异常和设备故障信息,并根据该标识发送指令到移动终端获取所述运行信息。
12. 根据权利要求11所述的服务器,其特征在于,所述服务器进一步包 括一个异常及故障判断模块;所述异常及故障判断模块用于判断出现的所述运行信息的类型;所述类型 至少包括内部故障、外部故障;所述内部故障至少包括死机、死屏;所述外部故障至少包括网络信号 没有达到预定强度。
本发明提供一种对函数运行进行跟踪的移动终端、方法及服务器,其中,移动终端包括指令模块、数据处理模块和诊断引擎模块;所述数据处理模块用于执行移动终端的业务功能,并分布形式设置或插入在所述源程序的预定位置;所述指令模块设置在所述数据处理模块的预定位置,用于跟踪所述数据处理模块中调用函数的运行信息;所述诊断引擎模块包括函数进入模块及函数退出模块,用于发送所述运行信息。应用上述技术方案,使得在移动终端的运行过程中,不再需要对调用函数的过程进行大量的跟踪记录,节省了所占用移动终端的资源,而且不会降低移动终端原有的运行速度。
文档编号H04W88/18GKSQ
公开日日 申请日期日 优先权日日
发明者王昌正 申请人:北京摩软科技有限公司无服务器微服务
发表于 17:04|
来源blogs|
作者Tim Wagner
摘要:在LinuxCon/ContainerCon 2015会议上,我做了一个以演示驱动,名为Microservices without the Servers(《无服务器微服务》)的演讲.
会议上,我做了一个以演示驱动,名为
(《无服务器微服务》)的演讲。在这篇演讲中,我创建了一项图像处理微服务,将它部署到多个区域,构建了一个以该服务为后端的移动应用,使用Amazon
API Gateway和一个网站添加了一个基于HTTPS的API,然后对其进行单元和负载测试,所有这些都没有使用任何服务器。
本博客详细地再现了这篇演讲,带你逐步浏览每一步所必需的细节,更深入地了解这一架构。想要查看高层次的概述,参阅
。想要查看该架构的另一个实例,查看可执行要点库,
无服务器架构
“无服务器”,我们是指不需要显式的基础设施,就像无服务器,无服务器上的部署,无任何种类的软件***。我们将仅使用托管的云服务和一个笔记本电脑。下面的图表阐明了这一架构的高级组件和它们之间的连接:一个Lambda函数能作为计算(“后端”)和一个直接连接到该函数的移动应用,加上Amazon
API Gateway为一个静态的Amazon S3承载的网站提供一个HTTP端点。
适用于使用AWS Lambda函数的移动和Web应用的无服务器架构
现在就让我们开始构建这一架构吧!
第一步:创建图像处理服务
为了使这一过程比较容易实施,我们将使用一个库,该库是一个内置库,使用Lambda的nodejs语言,ImageMagick。但是,这不是必须的-如果你更喜欢用自己的库,你可以
。下面的示例是用nodejs语言实施的,但是你也可以使用Java,Clojure,Scala,或AWS Lambda中其他的基于jvm的语言构建该服务。
下面的代码是一种适用于ImageMagick的“hello world”程序-它给了我们一个基本的命令结构(又叫做,一个切换语句),使我们能提取并返回内置的玫瑰图像。除了将结果进行编码所以它能以JSON格式快乐地存在外,其他没有什么。
var im = require("imagemagick");
var fs = require("fs");
exports.handler = function(event, context) {
if (event.operation) console.log("Operation " + event.operation + " requested");
switch (event.operation) {
case 'ping': context.succeed('pong');
case 'getSample':
event.customArgs = ["rose:", "/tmp/rose.png"];
im.convert(event.customArgs, function(err, output) {
if (err) context.fail(err);
var resultImgBase64 = new Buffer(fs.readFileSync("/tmp/rose.png")).toString('base64');
try {fs.unlinkSync("/tmp/rose.png");} catch (e) {} // discard
context.succeed(resultImgBase64);
// allow callback to complete
var error = new Error('Unrecognized operation "' + event.operation + '"');
context.fail(error);
首先,让我们在AWS Lambda控制台的测试窗口中给它发送如下JSON命令确保服务正在运行:
"operation": "ping"
}你应该能获得必不可少的“pong”响应。下一步,我们发送与下面的内容相类似的JSON命令来实际调用ImageMagick:
"operation": "getSample"
}该请求提取一个base64编码的字符串,该字符串代表一幅PNG格式的玫瑰图片:iVBORw0KGg…Jggg==。为了确保这不是一些随机字符,将其复制粘贴(没有双引号)到任何一个便利的“Base64图像”解码器,例如
。你应该可以看到一幅美丽的玫瑰图片:
示例图像(红玫瑰)
现在,让我们显示它周围的nodejs包装器的剩余部分,完成图像处理服务。我们将会提供一些不同的操作:
oPing:验证服务可用。
ogetDimensions:调用identify操作来提取图像宽度和高度的简写。
oidentify:提取图像元数据。
oResize:重新定义大小(在内部调用convert程序)的便利程序。
oThumbnail:resize的同义词。
oconvert:万能程序-可以转换媒体格式,运用转换,重新定义大小等。
ogetSample:提取一个示例图像;是“hello world”操作。
代码的大部分是对nodejs ImageMagick程序非常简单的包装,这些程序中的一些采用JSON格式(在这种情况下,被传递到Lambda的事件被清扫干净并被转发出去),另一些程序则采用命令行(也称作,自定义)参数,这些参数作为一个字符串组被传递。如果你以前没有使用过ImageMagick,这其中可能不明显的一部分是它作为一种包装器,运行于命令行之上,文件名称有语义含义。我们有两个相互矛盾的需求:我们想要客户端传达语义学含义(例如,图像的输出格式,如PNG格式还是JPEG格式),但是我们想要服务的创建者来决定磁盘上的临时存储位置以便我们不会泄露实施细节。为了一次完成这两个需求,我们在JSON模式中定义了两个参数:“inputExtension”和“outputExtension”,然后我们将客户端的一部分(文件扩展名)和服务器的一部分(目录和基名)结合来构建文件的实际位置。你可以在
中看到(并使用)已完成的代码。
这里你可以运行很多测试(后面我们会做更多),但是作为一个快速的健康检查,再次提取示例玫瑰图像,然后使用一个否定(颜色反转)过滤器将其传递回去。你可以在Lambda控制台使用像下面一样的JSON命令,只需将base64Image字段替换成实际的图像字符(将这里写在博客页上有点长)。
"operation": "convert",
"customArgs": [
"outputExtension": "png",
"base64Image": "...fill this in with the rose sample image, base64-encoded..."
}输出结果,被解码成一幅图像,应该是不可捉摸的植物,一支蓝色玫瑰:
蓝色玫瑰(反转红色玫瑰示例图像的结果)
所以,剩下的就是该服务的功能方面。一般地,这就是它开始变得令人厌恶的地方,从“一次性运作”到“可伸缩,可靠的服务,提供全年每天24小时的监控和生产日志”。但是,那正是Lambda的伟大之处:我们的图像处理代码已经是一个全面部署的,具有生产优势的微服务。下面,让我们添加一个可以调用该服务的移动应用...
第二步:创建一个移动客户端
你可以通过许多方式访问我们的图像处理微服务,但是为了展示一个示例客户端,我们将会构建一个简易Android应用。下面我将展示在ContainerCon演讲中用来创建简易Android应用的客户端侧代码,该简易Android应用可以使你选取一个图像,一个过滤器,然后通过AWS
Lambda中正在运行的图像处理服务中调用convert操作来展示应用过滤器到图像所产生的效果。&
为了直观地了解应用所做的事情,下面是它的一个示例图像,AWS Lambda Icon:
Android模拟器展示AWS Lambda Icon图像
我们将会挑选出“negate”过滤器来转换图标中的颜色
挑选‘Negate’图像转换过滤器
..and here’s the result: A blue version of our (originally orange) Lambda
moniker:下面是转换的结果:我们的(最初是橙色的)Lambda标记的蓝色版本:
挑选‘Negate’图像转换过滤器
..and here’s the result: A blue version of our (originally orange) Lambda
moniker:下面是转换的结果:我们的(最初是橙色的)Lambda标记的蓝色版本:
‘Negate’过滤器应用于AWS Lambda图标的结果
我们也可以选择西雅图图像,应用一个陈旧效果过滤器来给现代的西雅图天际线一种古老世界的感觉:
富有陈旧效果的西雅图天际线
现在让我们来讨论代码。在这里我不是在努力地教大家基本的Android编程,所以我将只聚焦于该应用中Lambda特定的元素。(如果你正在创建自己的应用,你也会需要包含
文件来运行下面的示例代码。)概念上讲,有以下四部分:
1.POJO数据模式
2.远程服务(操作)定义
4.服务调用
我们将会依次看一下每一部分:
数据模式定义了需要在客户端和服务器之间传递的对象。在这里没有Lambda机制;这些对象只是传统Java对象(Plain Old Java Objects,POJOs
),没有特别的库或框架。我们定义一个基本事件,然后将其扩展来反映我们的操作结构-你可以把这想象成JSON格式的Java化,在上面定义和测试图像处理服务时我们曾用到过JSON格式。如果你当时也是以Java格式写入服务器,很典型地,你将将这些文件作为常见的事件结构定义过程的一部分进行共享;在我们的示例中,这些POJO在服务器侧转化成JSON格式。
LambdaEvent.java
package com.amazon.lambda.androidimageprocessor.
public class LambdaEvent {
public String getOperation() {}
public void setOperation(String operation) {this.operation =}
public LambdaEvent(String operation) {setOperation(operation);}
}ImageConvertRequest.java
package com.amazon.lambda.androidimageprocessor.
import java.util.L
public class ImageConvertRequest extends LambdaEvent {
private String base64I
private String inputE
private String outputE
private List customA
public ImageConvertRequest() {super("convert");}
public String getBase64Image() {return base64I}
public void setBase64Image(String base64Image) {this.base64Image = base64I}
public String getInputExtension() {return inputE}
public void setInputExtension(String inputExtension) {this.inputExtension = inputE}
public String getOutputExtension() {return outputE}
public void setOutputExtension(String outputExtension) {this.outputExtension = outputE}
public List getCustomArgs() {return customA}
public void setCustomArgs(List customArgs) {this.customArgs = customA}
}到目前为止,情况还不是很复杂。既然我们有了一个数据模型,我们将使用一些Java注解来定义服务的端点。在这里我们将会揭露两个操作,“ping”和“convert”;将其进行扩展来包含其他的操作会比较简单,但是下面的示例应用,我们不需要其他的操作。
ILambdaInvoker.java
package com.amazon.lambda.androidimageprocessor.
import com.amazonaws.mobileconnectors.lambdainvoker.LambdaF
import java.util.M
public interface ILambdaInvoker {
@LambdaFunction(functionName = "ImageProcessor")
String ping(Map event);
@LambdaFunction(functionName = "ImageProcessor")
String convert(ImageConvertRequest request);
}现在我们已经准备好做应用的主要部分了。这其中的多数是Android样板代码或简单的客户端侧资源管理,但是我们将指出Lambda相关的两个部分:
这就是“init”部分,它创建鉴权供应商来调用Lambda API,创建一个Lambda调用器,该调用器可以调用上面定义的端点,在我们的数据模型中传递POJO:
// Create an instance of CognitoCachingCredentialsProvider
CognitoCachingCredentialsProvider cognitoProvider = new CognitoCachingCredentialsProvider(
this.getApplicationContext(), "us-east-1:&YOUR COGNITO IDENITY POOL GOES HERE&", Regions.US_EAST_1);
// Create LambdaInvokerFactory, to be used to instantiate the Lambda proxy.
LambdaInvokerFactory factory = new LambdaInvokerFactory(this.getApplicationContext(),
Regions.US_EAST_1, cognitoProvider);
// Create the Lambda proxy object with a default Json data binder.
lambda = factory.build(ILambdaInvoker.class);
另一个有趣(嗯,是有点有趣)的代码部分是实际的远程步骤调用本身:
return lambda.convert(params[0]);
} catch (LambdaFunctionException e) {
Log.e("Tag", "Failed to convert image");
实际上它并不是那么有趣因为魔法(参数序列化和结果还原序列化)正在后台发生,这里只留下一些错误需要处理。
下面是完整的源文件:
package com.amazon.lambda.a
import android.app.A
import android.app.ProgressD
import android.graphics.B
import android.graphics.BitmapF
import android.os.AsyncT
import android.os.B
import android.util.Base64;
import android.util.L
import android.view.V
import android.widget.ImageV
import android.widget.S
import android.widget.T
import com.amazon.lambda.androidimageprocessor.lambda.ILambdaI
import com.amazon.lambda.androidimageprocessor.lambda.ImageConvertR
import com.amazonaws.auth.CognitoCachingCredentialsP
import com.amazonaws.mobileconnectors.lambdainvoker.LambdaFunctionE
import com.amazonaws.mobileconnectors.lambdainvoker.LambdaInvokerF
import com.amazonaws.regions.R
import java.io.ByteArrayOutputS
import java.util.ArrayL
import java.util.HashM
import java.util.L
import java.util.M
import java.util.O
public class MainActivity extends Activity {
private ILambdaI
private ImageView selectedI
private String selectedImageBase64;
private ProgressDialog progressD
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Create an instance of CognitoCachingCredentialsProvider
CognitoCachingCredentialsProvider cognitoProvider = new CognitoCachingCredentialsProvider(
this.getApplicationContext(), "us-east-1:2a40105a-b330-43cf-8d4e-b647d492e76e", Regions.US_EAST_1);
// Create LambdaInvokerFactory, to be used to instantiate the Lambda proxy.
LambdaInvokerFactory factory = new LambdaInvokerFactory(this.getApplicationContext(),
Regions.US_EAST_1, cognitoProvider);
// Create the Lambda proxy object with a default Json data binder.
lambda = factory.build(ILambdaInvoker.class);
// ping lambda function to make sure everything is working
pingLambda();
// ping the lambda function
@SuppressWarnings("unchecked")
private void pingLambda() {
Map event = new HashMap();
event.put("operation", "ping");
// The Lambda function invocation results in a network call.
// Make sure it is not called from the main thread.
new AsyncTask&Map, Void, String&() {
protected String doInBackground(Map... params) {
// invoke "ping" method. In case it fails, it will throw a
// LambdaFunctionException.
return lambda.ping(params[0]);
} catch (LambdaFunctionException lfe) {
Log.e("Tag", "Failed to invoke ping", lfe);
protected void onPostExecute(String result) {
if (result == null) {
// Display a quick message
Toast.makeText(MainActivity.this, "Made contact with AWS lambda", Toast.LENGTH_LONG).show();
}.execute(event);
// event handler for "process image" button
public void processImage(View view) {
// no image has been selected yet
if (selectedImageBase64 == null) {
Toast.makeText(this, "Please tap one of the images above", Toast.LENGTH_LONG).show();
// get selected filter
String filter = ((Spinner) findViewById(R.id.filter_picker)).getSelectedItem().toString();
// assemble new request
ImageConvertRequest request = new ImageConvertRequest();
request.setBase64Image(selectedImageBase64);
request.setInputExtension("png");
request.setOutputExtension("png");
// custom arguments per filter
List customArgs = new ArrayList();
request.setCustomArgs(customArgs);
switch (filter) {
case "Sepia":
customArgs.add("-sepia-tone");
customArgs.add("65%");
case "Black/White":
customArgs.add("-colorspace");
customArgs.add("Gray");
case "Negate":
customArgs.add("-negate");
case "Darken":
customArgs.add("-fill");
customArgs.add("black");
customArgs.add("-colorize");
customArgs.add("50%");
case "Lighten":
customArgs.add("-fill");
customArgs.add("white");
customArgs.add("-colorize");
customArgs.add("50%");
// async request to lambda function
new AsyncTask() {
protected String doInBackground(ImageConvertRequest... params) {
return lambda.convert(params[0]);
} catch (LambdaFunctionException e) {
Log.e("Tag", "Failed to convert image");
protected void onPostExecute(String result) {
// if no data was returned, there was a failure
if (result == null || Objects.equals(result, "")) {
hideLoadingDialog();
Toast.makeText(MainActivity.this, "Processing failed", Toast.LENGTH_LONG).show();
// otherwise decode the base64 data and put it in the selected image view
byte[] imageData = Base64.decode(result, Base64.DEFAULT);
selectedImage.setImageBitmap(BitmapFactory.decodeByteArray(imageData, 0, imageData.length));
hideLoadingDialog();
}.execute(request);
showLoadingDialog();
Select methods for each image
public void selectLambdaImage(View view) {
selectImage(R.drawable.lambda);
selectedImage = (ImageView) findViewById(R.id.static_lambda);
Toast.makeText(this, "Selected image 'lambda'", Toast.LENGTH_LONG).show();
public void selectSeattleImage(View view) {
selectImage(R.drawable.seattle);
selectedImage = (ImageView) findViewById(R.id.static_seattle);
Toast.makeText(this, "Selected image 'seattle'", Toast.LENGTH_LONG).show();
public void selectSquirrelImage(View view) {
selectImage(R.drawable.squirrel);
selectedImage = (ImageView) findViewById(R.id.static_squirrel);
Toast.makeText(this, "Selected image 'squirrel'", Toast.LENGTH_LONG).show();
public void selectLinuxImage(View view) {
selectImage(R.drawable.linux);
selectedImage = (ImageView) findViewById(R.id.static_linux);
Toast.makeText(this, "Selected image 'linux'", Toast.LENGTH_LONG).show();
// extract the base64 encoded data of the drawable resource `id`
private void selectImage(int id) {
Bitmap bmp = BitmapFactory.decodeResource(getResources(), id);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
pressFormat.PNG, 100, stream);
selectedImageBase64 = Base64.encodeToString(stream.toByteArray(), Base64.DEFAULT);
// reset images to their original state
public void reset(View view) {
((ImageView) findViewById(R.id.static_lambda)).setImageDrawable(getResources().getDrawable(R.drawable.lambda, getTheme()));
((ImageView) findViewById(R.id.static_seattle)).setImageDrawable(getResources().getDrawable(R.drawable.seattle, getTheme()));
((ImageView) findViewById(R.id.static_squirrel)).setImageDrawable(getResources().getDrawable(R.drawable.squirrel, getTheme()));
((ImageView) findViewById(R.id.static_linux)).setImageDrawable(getResources().getDrawable(R.drawable.linux, getTheme()));
Toast.makeText(this, "Please choose from one of these images", Toast.LENGTH_LONG).show();
private void showLoadingDialog() {
progressDialog = ProgressDialog.show(this, "Please wait...", "Processing image", true, false);
private void hideLoadingDialog() {
progressDialog.dismiss();
移动应用上就是这些:一个数据模型(也称作Java类别),一个控制模型(也称作两个方法),三个初始化语句,然后是携带一个try/catch代码块的远程调用...很简单的东西。
多区域部署
到目前为止,我们还没怎么说及代码的运行位置。Lambda负责在一个区域内部署代码,但是你需要决定你想要在哪些区域运行该代码。在我最初的演示中,我最初在us-east-1区域,也称作Virginia数据中心,构建了该函数。为了兑现我们在摘要中所做的构建全球服务的宣言,让我们将区域扩展至eu-west-1 (Ireland)和ap-northeast-1 (Tokyo)以便移动应用可以从世界各地进行低时延的连接:
无服务器机制,在两个其他区域部署Lambda函数
这一个我们已经在博客中讨论过了:在中,我展示了如何使用一个Lambda函数在Amazon S3中部署以ZIP文件形式存储的其他多个Lambda函数。在ContainerCon的演讲中,我们也打开了复制功能,使其变得稍微时髦了一些,这样我们就可以以ZIP文件的形式上传图像处理服务到爱尔兰,使S3自动将服务复制到东京,然后使两个区域在各自的区域中将服务自动部署到相关联的Lambda服务中。你会爱上无服务器解决方案的)。
无服务器Web应用,第一部分:API端点
既然我们已经拥有了一个移动应用和一个全球部署的图像处理服务作为移动应用的后端,让我们将注意力转移到为那些偏爱浏览器胜过设备的人创建一个无服务器web应用。我们将会分两部分完成:首先,我们会为图像处理服务创建一个API端点。然后在下一部分,我们将会使用Amazon
S3添加实际的网站。
AWS Lambda使代码转换为服务变得简单的方法之一就是提供一个web服务前端,“built in”。但是,这需要客户端(像我们在上一部分构建的移动客户端)使用AWS提供的***来签署请求。这在我们的Android应用中是由
鉴权客户端处理的,但是如果我们想通过一个网站提供图像处理服务的公共访问又会怎样呢?
为了达到这一目的,我们将会求助于另一个服务器,
。这项服务使你能够定义一个API而不需要任何基础设施-API完全受AWS管理。我们将会使用API网关来为图像处理服务创建一个URL,该URL为网上的任意一个用户提供对它的一个能力子集的访问。Amazon
API Gateway提供各种方法来控制对API的访问:API调用可以使用AWS***来签署,你可以使用OAuth令牌,仅转发令牌头域进行验证,你可以使用API密钥(不推荐作为确保访问安全的方法),或将一个API完全公开,正如我们这里将会展示的。
除了各种各样的访问模型,API Gateway还有许多特性,在这篇帖子中我们就不进行探索了。一些特性是内置的(像反DDOS保护),其他的,像缓存,会使我们在反复提取流行图像时能够进一步缩短时延,降低成本。通过在客户端和(微)服务之间插入一个间接层,API
Gateway也使通过它的版本和阶段特性独立地演进各个服务变成了可能。但是现在,我们将会聚焦于基本任务,将图像处理服务作为一个API进行显示。
好,让我们创建我们的API。在AWS Console中,选择API Gateway,然后选择“New API”,为该API指定一个名称并提供一个选择性描述。在我的示例中,我将其命名为“ImageAPI”。
下一步,为你的新API创建一项资源(我称其为“ImageProcessingService”),然后在资源内部创建一个POST方法。选择“Lambda function”作为集成类型,输入你正在作为图像处理服务使用的Lambda函数的名称。在“Method Request”配置区域中,将授权类型设置为“none”(也就是说,这将会是一个可以公开访问的端点)。这就差不多了。
为了测试集成结果,点击“Test”按钮:
然后提供一个测试负载,如{“operation”: “ping”}。你应该能够得到预期的“pong”结果,表明你已经成功地将你的API连接到了Lambda函数。
除此之外,后面我们将会有更多(更深层次)的测试,但是我发现有时很有用的一件事是在API中,在顶层资源中添加一个GET方法,一定会使一些事情变得简单,像ping操作,使我也能够按照预期,快速地从我的API连接的任何一个浏览器诊断我的Lambda函数。这次(或一般)演示不需要,但是你也可能发现它是有用的。
为了接下来的内容(S3静态内容),我们也需要打开CORS功能。这很简单但是有好几个步骤。API Gateway小组在继续努力,想使这变得更简单,所以没有在这里重复那些指令(可能很快就会使它们变得过时),我推荐您查看文档。
点击“Deploy this API”按钮。这样你应该就准备好创建网站了!
无服务器web应用,第二部分:Amazon S3承载的静态网站
这一部分很简单-上传下面的Javascript网站代码到你选择的S3桶中:
var ENDPOINT = 'https://fuexvelc41.execute-api.us-east-/prod/ImageProcessingService';
angular.module('app', ['ui.bootstrap'])
.controller('MainController', ['$scope', '$http', function($scope, $http) {
$scope.loading =
$scope.image = {
width: 100
$scope.ready = function() {
$scope.loading =
$scope.submit = function() {
var fileCtrl = document.getElementById('image-file');
if (fileCtrl.files && fileCtrl.files[0]) {
$scope.loading =
var fr = new FileReader();
fr.onload = function(e) {
$scope.image.base64Image = e.target.result.slice(e.target.result.indexOf(',') + 1);
$scope.$apply();
document.getElementById('original-image').src = e.target.
// Now resize!
$http.post(ENDPOINT, angular.extend($scope.image, { operation: 'resize', outputExtension: fileCtrl.value.split('.').pop() }))
.then(function(response) {
document.getElementById('processed-image').src = "data:image/base64," + response.
.catch(console.log)
.finally($scope.ready);
fr.readAsDataURL(fileCtrl.files[0]);
下面是我们在演示中用于(很基本的)网站的HTML源:
&!DOCTYPE html&
&html lang="en"&
&title&Image Processing Service&/title&
&meta charset="utf-8"&
&meta http-equiv="X-UA-Compatible" content="IE=edge"&
&meta name="viewport" content="width=device-width, initial-scale=1"&
&link rel="stylesheet" type="text/css" href="/ajax/libs/twitter-bootstrap/3.3.4/css/bootstrap.min.css"&
&link rel="stylesheet" type="text/css" href="/css?family=Open+Sans:400,700"&
&link rel="stylesheet" type="text/css" href="main.css"&
&body ng-app="app" ng-controller="MainController"&
&div class="container"&
&h1&Image Processing Service&/h1&
&div class="row"&
&div class="col-md-4"&
&form ng-submit="submit()"&
&div class="form-group"&
&label for="image-file"&Image&/label&
&input id="image-file" type="file"&
&div class="form-group"&
&label for="image-width"&Width&/label&
&input id="image-width" class="form-control" type="number"
ng-model="image.width" min="1" max="4096"&
&button type="submit" class="btn btn-primary"&
&span class="glyphicon glyphicon-refresh" ng-if="loading"&&/span&
&div class="col-md-8"&
&accordion close-others="false"&
&accordion-group heading="Original Image" is-open="true"&
&img id="original-image" class="img-responsive"&
&/accordion-group&
&accordion-group heading="Processed Image" is-open="true"&
&img id="processed-image" class="img-responsive"&
&/accordion-group&
&/accordion&
&script type="text/javascript" src="/ajax/libs/angular.js/1.3.15/angular.min.js"&&/script&
&script type="text/javascript" src="/ajax/libs/angular-ui-bootstrap/0.13.3/ui-bootstrap.min.js"&&/script&
&script type="text/javascript" src="/ajax/libs/angular-ui-bootstrap/0.13.3/ui-bootstrap-tpls.min.js"&&/script&
&script type="text/javascript" src="main.js"&&/script&
最后,这是CSS:body {
font-family: 'Open Sans', sans-
padding-bottom: 15
/** LOADER **/
.glyphicon-refresh {
-animation: spin .7
-webkit-animation: spin .7
@keyframes spin {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
@-webkit-keyframes spin {
from { -webkit-transform: rotate(0deg); }
to { -webkit-transform: rotate(360deg); }
然后打开S3提供的静态网站内容:
URL将取决于你的S3区域和对象的名称,如“http://image-processing-service.s3-website-us-east-/”。在一个浏览器中访问该URL,你应该能够看到你的图像网站:
单元和负载测试
有API Gateway为你的Lambda微服务提供一个传统的基于URL的接口,你有许多种选择进行测试。但是让我们坚持我们的无服务器方法,完全在没有基础设施或甚至客户端的情况下进行测试!
首先,我们想通过API进行调用。那很简单;我们使用Lambda的HTTPS调用蓝图来传到我们使用API Gateway部署时拥有的端点:
"options": {
"host": "fuexvelc41.execute-api.us-east-",
"path": "/prod/ImageProcessingService",
"method": "POST"
"operation": "getSample"
}现在我们拥有了样本,让我们在它周围包装一个单元测试。我们的单元测试工具并不是很有效果;它只是运行另一个Lambda函数,将结果存储到我们指定的一个Amazon
DynamoDB表中。在“单元测试”模式下,我们将会使用
"operation": "unit",
"function": "HTTPSInvoker",
"resultsTable": "unit-test-results",
"testId": "LinuxConDemo",
"event": {
"options": {
"host": "fuexvelc41.execute-api.us-east-",
"path": "/prod/ImageProcessingService",
"method": "POST"
"operation": "getSample"
}最后,我们将会多次运行单元测试来做一个简单的负载测试。我们将会再次使用Lambda
,这次是在“负载测试”模式下:
"operation": "load",
"iterations": 100,
"function": "TestHarness",
"event": {
"operation": "unit",
"function": "HTTPSInvoker",
"resultsTable": "unit-test-results",
"testId": "LinuxConLoadTestDemo",
"event": {
"options": {
"host": "fuexvelc41.execute-api.us-east-",
"path": "/prod/ImageProcessingService",
"method": "POST"
"operation": "getSample"
}下面是我们的无服务器测试架构的一张图片:
一个无服务器单元和负载测试工具
你可以轻松地变换这种方法,并入校验程序,运行各种单元测试等。如果你不需要web应用基础设施,你可以跳过API Gateway和HTTP调用,直接在你的单元测试中只运行图像处理服务。如果你想总结或分析测试输出,你可以轻松地将一个Lambda函数作为一个事件处理器附加到存储测试结果的DynamoDB表中。
这是一篇稍长的帖子,但是它是一个完整的程序包,包含构建一个真实的,可伸缩的后端服务,使其与移动客户端和一个网站相对,所有这些在系统的任何一部分,前端,后端,API,部署或测试中,都不需服务器或其他基础设。让我们走向无服务器时代!
原文链接:
活动推荐:
& & & & & & &&
& & & & & & & & & &
& & & & & & & & & & &
& & & & & & & & & & &
& & & & & & & & & & &
& & & & ( 翻译/吕冬梅 &责编/王鑫贺 )
订阅“AWS中文技术社区”微信公众号,实时掌握AWS技术及产品消息!
AWS中文技术社区为广大开发者提供了一个Amazon Web Service技术交流平台,推送AWS最新资讯、技术视频、技术文档、精彩技术博文等相关精彩内容,更有AWS社区专家与您直接沟通交流!快加入AWS中文技术社区,更快更好的了解AWS云计算技术。
推荐阅读相关主题:
CSDN官方微信
扫描二维码,向CSDN吐槽
微信号:CSDNnews
相关热门文章