首页 文章 精选 留言 我的

精选列表

搜索[get],共10005篇文章
优秀的个人博客,低调大师

get最IN工控安全技术,看匡恩网络权威报告

2017年伊始,匡恩网络发布了《2016年工业控制网络安全态势报告》(以下简称 “报告”),匡恩网络已连续三年撰写并发布报告。报告全面介绍了国内外工控系统网络安全发展现状以及当前所面临的主要问题,并在这些问题基础上提出了针对性的对策与建议。以下我们将从技术维度重点解读报告。 见微知著,深挖工控网络安全 报告开篇以全球视野角度分析了当前工业控制系统相关安全问题。文中指出,随着全球物联网技术的迅猛发展,工业控制系统安全逐步向工业物联网安全演化,各类工控安全漏洞数量不断增长造成重大安全事件频发,全球各国联网工业控制系统安全面临严重威胁,见下图所示。 图9 2016年全球重要工控安全事件分布图 2016年全球重要工控安全事件分布图 2016年,全球发达国家加快了工业控制网络安全领域发展的步伐,采取了加大资金投入、制定国家层面战略规划和行动计划、成立国家安全机构和学院、组建网络部队等多方面的措施,以提升本国网络安全保障能力。我国虽然在工业控制网络安全方面起步较晚,但发展迅速,在2016年先后颁布了《中华人民共和国网络安全法》、发布了6项工业控制系统安全相关标准、开展了全国关键信息基础设施网络安全检查和全国工业控制系统安全大检查等一系列行动。 在产业发展态势层面,文中对我国工业控制系统发展中面临的风险与隐患进行了介绍,主要体现在两个方面: (一) 联网工控设备日益增多,安全隐患日渐凸显 报告中披露了来源于匡恩网络工业控制网络威胁情报中心的统计数据,对我国暴露在互联网中的工控设备数量、类型进行了展示,从中我们可以发现联网设备中可编程逻辑控制器(PLC)数量最多。 此外,从文中工控网络安全漏洞历年的增长情况、工控厂商漏洞数量、漏洞类型等详细的数据统计我们可以感受到,国内主要工控设备厂商产品的安全性愈发令人担忧,尤其是PLC、SCADA、上位机软件的漏洞数量十分惊人,一旦被利用所造成的损失巨大。随着工控系统联网设备逐步增多,潜在安全漏洞数量也逐步增长,长此以往设备安全的不可控将成为我国工控网络安全的隐患点与风险源。 (二)各地区工控安全发展水平差异较大,平均水平偏低 报告中指出匡恩网络通过工业物联网安全大数据分析平台,结合近年来多次全国性的安全检查任务及安全研究和项目实践经验,对我国各区域、重点行业的工控网络安全水平进行了评价与分析。 根据各地区、各行业工控网络安全综合指数得分情况,我们不难发现全国各地区在工业控制系统保护措施方面普遍得分较低(平均76),华北、华东、华中较差,见下图所示。 各区域工控网络安全综合指数统计 各区域工控网络安全综合指数统计 虽然,我国华东、华北、华中等地区工业、公共设施相对其他区域发达,工业控制系统应用范围广、数量大、发展速度快,漏洞、病毒木马等网络威胁及基层防护薄弱等问题反而更加突出,是得分较低的主要原因。 另外,我国相关重点行业得分也不容乐观,大部分地区得分偏低,见下图所示。 重点行业工控安全综合指数统计 重点行业工控安全综合指数统计 得分较高的电力、烟草、航空、航天、交通行业受到了国家层面的重视,各方面工作取得了一定的成效,发现的问题也相对较少。得分较低的地区,主要在安全经费、安全事件、安全培训等管理方面存在缺失。 从各地区、各行业工控安全综合指数结果来看,反映出部分地区、行业面对工控网络安全工作缺乏全面的认识,在一定程度上限制了工控安全的发展。 匡恩网络基于自身对工控网络安全的深入理解,结合全国工业企业网络安全调研结果所反映的问题进行了总结,主要包括: 普遍存在工控网络边界防护机制缺失或无效,已经成为了普遍现象。 在设备投运前既没有进行加固处理,也没有采取补偿性控制措施,在线工控系统长期“带病”运行。 黑客入侵、病毒木马的网络攻击行为在工控网络中普遍存在,已经成为了破坏工控系统的主要形式。 大量国外工控设备在线运行,短期难以实现自主可控。 在安全管理问题上主要体现在两方面,一方面是行业标准体系不健全,缺乏引导和监管依据;另外一方面各单位重视程度不够,在组织、人员、投入等多方面资源匮乏,在两方面的综合作用下安全管理的“死角”、“短板”频现。 IN时代,最in技术开启未来 自工控网络安全被业界提出以来,国内外工业控制系统网络安全防护理念经历了一系列演变,匡恩网络进行了深入研究,进而提出了工控网络安全防护的总体思路与实践参考。 匡恩网络“4+1”安全防护理念 从匡恩网络提出“结构安全性、本体安全性、行为安全性、基因安全性、时间持续性”的内涵中,我们可以了解到匡恩网络把主动防护与被动防护的理念融入其中,同时引入安全防护机制、安全体系发展的思想,在攻击技术不断变化的条件下,确保企业的工业控制系统安全保障体系立于不败之地。 匡恩网络“4+1”工控网络安全防护理念 匡恩网络“4+1”工控网络安全防护理念 匡恩网络工控网络安全防护体系 报告中展示了匡恩网络构建的大型工控网络安全防护体系,见下图所示。 匡恩网络集团化公司整体工控网络安全蓝图 匡恩网络集团化公司整体工控网络安全蓝图 匡恩网络基于“4+1”工控网络安全防护理念,建立了以“集中管理、分层控制”为原则的持续性防御体系,适应集团多层级、多维度的管理需求,提供柔性化的管理框架,支持三级单位防护设备的水平扩展,既保护了客户硬件投资,又提高了管理效率。 另外,匡恩网络安全产品秉承了“4+1”工控安全防护理念,采用了“外挂”的部署方式,适应工业环境稳定性、可靠性、完整性以及网络延时低的要求,提供了系统检测平台、智能保护平台、检测审计平台及安全大数据平台等多样化的产品系列以满足各行业的不同需求,为客户提供定制化安全产品,见下图所示。 匡恩网络由工业控制系统内部生长的持续性防御体系 此外,匡恩网络还在安全芯片、可信计算技术方面不断进行探索,力求向工控网络安全的更底层技术下沉,联同广大安全厂商共同打造绿色产业生态环境。 匡恩网络PDCA安全环整体服务方案 匡恩网络基于全生命周期的安全服务方案,囊括计划准备、方案实施、结果评估和优化提升四大阶段,如下图所示。 匡恩网络PDCA安全环 匡恩网络PDCA安全环 每个阶段都为客户安全建设提供了丰富的服务内容,其中包括设备检测、安全服务、威胁管理、监控审计、智能保护、安全数据库等多个方面。 持续创新是推动产业发展的不竭动力。匡恩网络的这些前沿创新技术和定制服务,在关键基础设施、智能制造、智慧城市、军民融合四大领域的十多个行业深度实施应用,取得了良好的效果和广泛的赞誉。相信,这些前沿技术与防护理念将为两化深度融合实施创造更多的可能性。 本文转自d1net(转载)

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

这两大策略要get住

僵尸网络日益强大和主动,并且武装得比以往更强悍。据Neustar的报告,在2016年第一季度,僵尸网络发动的攻击达到了3亿次,比2015年同期增长了300%,比2015年最后一季度增加了35%。 很多僵尸网络都被用于发动更强大和更频繁的分布式拒绝服务攻击(DDoS)。Neustar的报告指出,有73%的用户称在2015年遭受了DDoS攻击,而其中的82%反复遭到攻击。僵尸网络还被用于对失窃的登录凭据进行大规模的复杂恶意测试,并查找可轻松利用的系统漏洞。 由于物联网设备加入到被僵尸网络控制的设备中,问题变得更为复杂。最近,安全博主Brian Krebs的网站遭受了历史上最强大的一次DDoS攻击,经证实,由路由器、安全摄像机(监控摄像机)、打印机、数字视频记录机(DVR)构成的大规模僵尸网络是发动此攻击的罪魁祸首。 随着僵尸网络攻击渐趋加强,企业如何更好地保护自己的网络? 两大策略 传统上,对于期望防御僵尸网络攻击的企业来说,可以使用两种主要的策略。第一个与网站和网络的能力有关,即企业应对进入网络的不可预料的峰值通信(由DDoS攻击导致)能力。基于真实网络测试的负载均衡策略通过分散通信量,从而有助于平衡通信的高峰和低谷,对于减轻DDoS企图的影响,这是一个重要方法。然而,即使有效的负载均衡策略也有可能被超大规模的DDoS攻击摧毁,导致应用程序陷于停顿。 第二大策略与实际的安全工具有关,例如防火墙,其关注的是确认和阻止恶意通信。这种策略很有效,但是需要积极地分析大量网络通信的能力,以及确认恶意数据包的能力,并且阻止这些恶意包的能力都给最新一代的高性能防火墙带来沉重负担。将海量的无关通信发给这种设备会极大地削弱其分析性能,从而又在整个网络中造成性能的大量消耗。 智能IP过滤 不过,我们还有第三种策略:首先要通过智能的预过滤来防止僵尸网络产生的恶意通信到达防火墙。这种方法极大地减少了攻击的强度和影响,同时还提高了防火墙和相关安全方案的效率,使得确认威胁和减少虚假的警报更为简单。 要实现此功能,企业需要一个专门的网关来持续监视和主动过滤被僵尸网络控制的IP地址。这个网关要利用实时的不断更新的威胁情报和应用程序关于恶意IP地址(这些地址是已经感染了僵尸的地址或者是保存恶意软件的地址)的情报。然后,在网关收到这些已知的恶意地址的通信时,就会自动地高速过滤掉这些地址,使其无法达到企业网络。 企业可以将同样的策略进行扩展,用以阻止来自企业无业务利益的整个地区的IP地址的通信,或阻止已存在威胁的某地区的IP地址通信。 找到漏洞 使用威胁情报网关来过滤IP通信还有一个好处:网关还可以确定已经存在于网络上的正在偷偷地发送敏感数据给罪犯的僵尸感染。这种网关还可以检查离开网络的通信:如果通信被发往一个已知的僵尸网络的恶意服务器地址,就过滤并自动阻止,永久断开数据泄露。 很明显,IP地址过滤策略的最直接的好处就是极大地减少企业遭受外部僵尸网络的DDoS攻击的机会,也可以阻止由于内部的僵尸感染而造成的数据泄露。但是这种方法还有其它的好处。企业现有的安全基础架构和IT团队可以更高效地发挥功能。一个典型的企业每周可能收到大约近两万次恶意软件警告,并且每年要花费大量金钱用于跟踪一些虚假警告。IP地址过滤可以减少警告次数和虚假的警告消息,从而解放IT团队的资源,减少在防火墙、反病毒、沙箱等方案上的处理成本,并且提升企业应对目标攻击的能力。 智能IP地址过滤利用威胁情报网关,给企业一种由策略驱动的网络通信控制,使企业阻止未知的、恶意的访问者,并且阻止由已有的感染造成的数据泄露和数据破坏。这是对付僵尸网络的一项关键举措。 本文转自d1net(转载)

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

Objective-C Runtime三种必备方法、轻松Get

前言 二年前的我就像一个装着三个空空如也的沙盒,当时对于iOS开发除了满腔空腹的热情,剩下的除了迷茫还是迷茫。利用大学空闲时间确立自己的学习路线。既然热爱编程,决定往技术领域发展,那么就静下心来闭关修炼。“路漫漫其修远兮 吾将上下而求索”!不知道当年的同学朋友们还有多少人在坚持写代码,也是时候总结分享一下自己学习进展以及成果了、希望能给读者们有所帮助及完成互联网的分享精神。 概括 本篇主要介绍Runtime在开发中最常用的三种实战使用场景以及Runtime简介让你更快速的上手。用最简单.易懂的方式让你认识Objective-C Runtime,教你如何使用Runtime交换两个方法的实现. Runtime给分类添加属性. Runtime获得某个对象的所有属性。 一、Runtime简介 Objective-C Runtime 是开源的是开源的,任何时候你都能从 http://opensource.apple.com或https://opensource.apple.com/tarballs/objc4/. 获取。事实上查看 Objective-C 源码是我理解它是如何工作的第一种方式,在这个问题上要比读苹果的文档要好。 因为Objc是一门动态语言,所以它总是想办法把一些决定工作从编译连接推迟到运行时。也就是说只有编译器是不够的,还需要一个运行时系统 (runtime system) 来执行编译后的代码。这就是 Objective-C Runtime 系统存在的意义,它是整个Objc运行框架的一块基石。 Objective-C 的 Runtime 是一个运行时库(Runtime Library),它是一个主要使用 C 和汇编写的库,为 C 添加了面相对象的能力并创造了 Objective-C。这就是说它在类信息(Class information) 中被加载,完成所有的方法分发,方法转发,等等。Objective-C runtime 创建了所有需要的结构体,让 Objective-C 的面相对象编程变为可能。也就是在运行时候的一些机制,其中最主要的是消息机制。 对于C语言,函数的调用在编译的时候会决定调用哪个函数。 对于OC的函数,属于动态调用过程,在编译的时候并不能决定真正调用哪个函数,只有在真正运行的时候才会根据函数的名称找到对应的函数来调用。 事实证明: 在编译阶段,OC可以调用任何函数,即使这个函数并未实现,只要声明过就不会报错。 在编译阶段,C语言调用未实现的函数就会报错。 二、runtime作用 1.发送消息 方法调用的本质,就是让对象发送消息。 objc_msgSend,只有对象才能发送消息,因此以objc开头. 使用消息机制前提,必须导入#import <objc/message.h> 消息机制简单使用 ####三、操作对象的类型的定义 /// An opaque type that represents a method in a class definition. 一个类型,代表着类定义中的一个方法 typedef struct objc_method *Method; /// An opaque type that represents an instance variable.代表实例(对象)的变量 typedef struct objc_ivar *Ivar; /// An opaque type that represents a category.代表一个分类 typedef struct objc_category *Category; /// An opaque type that represents an Objective-C declared property.代表OC声明的属性 typedef struct objc_property *objc_property_t; // Class代表一个类,它在objc.h中这样定义的 typedef struct objc_class *Class; struct objc_class { Class isa OBJC_ISA_AVAILABILITY; #if !__OBJC2__ Class super_class OBJC2_UNAVAILABLE; const char *name OBJC2_UNAVAILABLE; long version OBJC2_UNAVAILABLE; long info OBJC2_UNAVAILABLE; long instance_size OBJC2_UNAVAILABLE; struct objc_ivar_list *ivars OBJC2_UNAVAILABLE; struct objc_method_list **methodLists OBJC2_UNAVAILABLE; struct objc_cache *cache OBJC2_UNAVAILABLE; struct objc_protocol_list *protocols OBJC2_UNAVAILABLE; #endif } OBJC2_UNAVAILABLE; 这些类型的定义,对一个类进行了完全的分解,将类定义或者对象的每一个部分都抽象为一个类型type,对操作一个类属性和方法非常方便。OBJC2_UNAVAILABLE标记的属性是Ojective-C 2.0不支持的,但实际上可以用响应的函数获取这些属性,例如:如果想要获取Class的name属性,可以按如下方法获取:Class classPerson = Person.class; // printf("%s\n", classPerson->name); //用这种方法已经不能获取name了 因为OBJC2_UNAVAILABLE const char *cname = class_getName(classPerson); printf("%s", cname); // 输出:Person</pre> - ##四.函数的定义 对对象进行操作的方法一般以object_开头 对类进行操作的方法一般以class_开头 对类或对象的方法进行操作的方法一般以method_开头 对成员变量进行操作的方法一般以ivar_开头 对属性进行操作的方法一般以property_开头 对协议进行操作的方法一般以protocol_开头 根据以上的函数的前缀 可以大致了解到层级关系。对于以objc_开头的方法,则是runtime最终的管家,可以获取内存中类的加载信息,类的列表,关联对象和关联属性等操作。 例如:使用runtime对当前的应用中加载的类进行打印,别被吓一跳。 <pre>- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { unsigned int count = 0; Class *classes = objc_copyClassList(&count); for (int i = 0; i < count; i++) { const char *cname = class_getName(classes[i]); printf("%s\n", cname); } } 五实战应用场景 5_1 Runtime交换两个方法的实现:因系统自带的方法功能不够,给系统自带的方法扩展一些功能,并且保持原有的功能。 方式一:继承系统的类,重写方法. 方式二:使用runtime,交换方法. @implementation ViewController -(void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. // 需求:给imageNamed方法提供功能,每次加载图片就判断下图片是否加载成功。 // 步骤一:先搞个分类,定义一个能加载图片并且能打印的方法+ (instancetype)imageWithName:(NSString *)name; // 步骤二:交换imageNamed和imageWithName的实现,就能调用imageWithName,间接调用imageWithName的实现。 UIImage *image = [UIImage imageNamed:@"123"]; } @end @implementation UIImage (Image) // 加载分类到内存的时候调用 +(void)load { // 交换方法 // 获取imageWithName方法地址 Method imageWithName = class_getClassMethod(self, @selector(imageWithName:)); // 获取imageWithName方法地址 Method imageName = class_getClassMethod(self, @selector(imageNamed:)); // 交换方法地址,相当于交换实现方式 method_exchangeImplementations(imageWithName, imageName); } // 不能在分类中重写系统方法imageNamed,因为会把系统的功能给覆盖掉,而且分类中不能调用super. // 既能加载图片又能打印 +(instancetype)imageWithName:(NSString *)name { // 这里调用imageWithName,相当于调用imageName UIImage *image = [self imageWithName:name]; if (image == nil) { NSLog(@"加载空的图片"); } return image; } @end 5_2给分类添加属性 原理:给一个类声明属性,其实本质就是给这个类添加关联,并不是直接把这个值的内存空间添加到类存空间 @implementation ViewController -(void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. // 给系统NSObject类动态添加属性name NSObject *objc = [[NSObject alloc] init]; objc.name = @"小码哥"; NSLog(@"%@",objc.name); } @end // 定义关联的key static const char *key = "name"; @implementation NSObject (Property) - (NSString *)name { // 根据关联的key,获取关联的值。 return objc_getAssociatedObject(self, key); } -(void)setName:(NSString *)name { // 第一个参数:给哪个对象添加关联 // 第二个参数:关联的key,通过这个key获取 // 第三个参数:关联的value // 第四个参数:关联的策略 objc_setAssociatedObject(self, key, name, OBJC_ASSOCIATION_RETAIN_NONATOMIC); } @end 5_3.Runtime获得某个对象的所有属性 对于获取成员变量的列表可以使用class_copyIvarList函数,如果想要获取属性列表可以使用class_copyPropertyList函数,使用的示例如下: - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { Class classPerson = NSClassFromString(@"Person"); // 与下面一句效果一样,可以不用导入头文件 // Class clazz = Person.class; unsigned int count = 0; Ivar *ivarList = class_copyIvarList(classPerson, &count); // 获取成员变量数组 for (int i = 0; i < count; i++) { const char *cname = ivar_getName(ivarList[i]); // 获取成员变量的名字 NSString *name = [NSString stringWithUTF8String:cname]; NSLog(@"%@", name); } NSLog(@"-------------------分割线------------------"); objc_property_t *propertyList = class_copyPropertyList(classPerson, &count); // 获取属性数组 for (int i = 0; i < count; i++) { const char *cname = property_getName(propertyList[i]); NSString *name = [NSString stringWithUTF8String:cname]; NSLog(@"%@", name); } } 5_4字典转模型 设计模型:字典转模型的第一步 模型属性,通常需要跟字典中的key一一对应 问题:一个一个的生成模型属性,很慢? 需求:能不能自动根据一个字典,生成对应的属性。 解决:提供一个分类,专门根据字典生成对应的属性字符串。 @implementation NSObject (Log) // 自动打印属性字符串 +(void)resolveDict:(NSDictionary *)dict{ // 拼接属性字符串代码 NSMutableString *strM = [NSMutableString string]; // 1.遍历字典,把字典中的所有key取出来,生成对应的属性代码 [dict enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) { 类型经常变,抽出来 NSString *type; if ([obj isKindOfClass:NSClassFromString(@"__NSCFString")]) { type = @"NSString"; }else if ([obj isKindOfClass:NSClassFromString(@"__NSCFArray")]){ type = @"NSArray"; }else if ([obj isKindOfClass:NSClassFromString(@"__NSCFNumber")]){ type = @"int"; }else if ([obj isKindOfClass:NSClassFromString(@"__NSCFDictionary")]){ type = @"NSDictionary"; } // 属性字符串 NSString *str; if ([type containsString:@"NS"]){ { str = [NSString stringWithFormat:@"@property (nonatomic, strong) %@ *%@;",type,key]; }else{ str = [NSString stringWithFormat:@"@property (nonatomic, assign) %@ %@;",type,key]; } // 每生成属性字符串,就自动换行。 [strM appendFormat:@"\n%@\n",str]; }]; // 把拼接好的字符串打印出来,就好了。 NSLog(@"%@",strM); } @end 字典转模型的方式一:KVC @implementation Status +(instancetype)statusWithDict:(NSDictionary *)dict { Status *status = [[self alloc] init]; [status setValuesForKeysWithDictionary:dict]; return status; } @end KVC字典转模型弊端:必须保证,模型中的属性和字典中的key一一对应。 如果不一致,就会调用[<Status 0x7fa74b545d60> setValue:forUndefinedKey:] 报key找不到的错。 分析:模型中的属性和字典的key不一一对应,系统就会调用setValue:forUndefinedKey:报错。 解决:重写对象的setValue:forUndefinedKey:,把系统的方法覆盖, 就能继续使用KVC,字典转模型了。 字典转模型的方式二:Runtime 思路:利用运行时,遍历模型中所有属性,根据模型的属性名,去字典中查找key,取出对应的值,给模型的属性赋值。 步骤:提供一个NSObject分类,专门字典转模型,以后所有模型都可以通过这个分类转。 @implementation ViewController -(void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. // 解析Plist文件 NSString *filePath = [[NSBundle mainBundle] pathForResource:@"status.plist" ofType:nil]; NSDictionary *statusDict = [NSDictionary dictionaryWithContentsOfFile:filePath]; // 获取字典数组 NSArray *dictArr = statusDict[@"statuses"]; // 自动生成模型的属性字符串 // [NSObject resolveDict:dictArr[0][@"user"]]; _statuses = [NSMutableArray array]; // 遍历字典数组 for (NSDictionary *dict in dictArr) { Status *status = [Status modelWithDict:dict]; [_statuses addObject:status]; } // 测试数据 NSLog(@"%@ %@",_statuses,[_statuses[0] user]); } @end @implementation NSObject (Model) +(instancetype)modelWithDict:(NSDictionary *)dict { // 思路:遍历模型中所有属性-》使用运行时 // 0.创建对应的对象 id objc = [[self alloc] init]; // 1.利用runtime给对象中的成员属性赋值 // class_copyIvarList:获取类中的所有成员属性 // Ivar:成员属性的意思 // 第一个参数:表示获取哪个类中的成员属性 // 第二个参数:表示这个类有多少成员属性,传入一个Int变量地址,会自动给这个变量赋值 // 返回值Ivar *:指的是一个ivar数组,会把所有成员属性放在一个数组中,通过返回的数组就能全部获取到。 /* 类似下面这种写法 Ivar ivar; Ivar ivar1; Ivar ivar2; // 定义一个ivar的数组a Ivar a[] = {ivar,ivar1,ivar2}; // 用一个Ivar *指针指向数组第一个元素 Ivar *ivarList = a; // 根据指针访问数组第一个元素 ivarList[0]; */ unsigned int count; // 获取类中的所有成员属性 Ivar *ivarList = class_copyIvarList(self, &count); for (int i = 0; i < count; i++) { // 根据角标,从数组取出对应的成员属性 Ivar ivar = ivarList[i]; // 获取成员属性名 NSString *name = [NSString stringWithUTF8String:ivar_getName(ivar)]; // 处理成员属性名->字典中的key // 从第一个角标开始截取 NSString *key = [name substringFromIndex:1]; // 根据成员属性名去字典中查找对应的value id value = dict[key]; // 二级转换:如果字典中还有字典,也需要把对应的字典转换成模型 // 判断下value是否是字典 if ([value isKindOfClass:[NSDictionary class]]) { // 字典转模型 // 获取模型的类对象,调用modelWithDict // 模型的类名已知,就是成员属性的类型 // 获取成员属性类型 NSString *type = [NSString stringWithUTF8String:ivar_getTypeEncoding(ivar)]; // 生成的是这种@"@\"User\"" 类型 -》 @"User" 在OC字符串中 \" -> ",\是转义的意思,不占用字符 // 裁剪类型字符串 NSRange range = [type rangeOfString:@"\""]; type = [type substringFromIndex:range.location + range.length]; range = [type rangeOfString:@"\""]; // 裁剪到哪个角标,不包括当前角标 type = [type substringToIndex:range.location]; // 根据字符串类名生成类对象 Class modelClass = NSClassFromString(type); if (modelClass) { // 有对应的模型才需要转 // 把字典转模型 value = [modelClass modelWithDict:value]; } } // 三级转换:NSArray中也是字典,把数组中的字典转换成模型. // 判断值是否是数组 if ([value isKindOfClass:[NSArray class]]) { // 判断对应类有没有实现字典数组转模型数组的协议 if ([self respondsToSelector:@selector(arrayContainModelClass)]) { // 转换成id类型,就能调用任何对象的方法 id idSelf = self; // 获取数组中字典对应的模型 NSString *type = [idSelf arrayContainModelClass][key]; // 生成模型 Class classModel = NSClassFromString(type); NSMutableArray *arrM = [NSMutableArray array]; // 遍历字典数组,生成模型数组 for (NSDictionary *dict in value) { // 字典转模型 id model = [classModel modelWithDict:dict]; [arrM addObject:model]; } // 把模型数组赋值给value value = arrM; } } if (value) { // 有值,才需要给模型的属性赋值 // 利用KVC给模型中的属性赋值 [objc setValue:value forKey:key]; } } return objc; } @end 此篇文章是对网上现有资料的一个版本进行理解剖析。 感谢你能耐心读完。 希望能对在Runtime上有所帮助、喜欢的可以点一下关注作者或者️谢谢-------

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

如何get一个终身免费续期的定制数字人?

想拥有一个“数字分身” 吗?给你一个终身免费续期的特权。 定制周期长?训练、运营成本高?成片效果生硬?无法应用于实际场景? 随着AIGC技术的快速发展,虚拟数字人的生成效率不断提高,训练成本逐渐降低,与此同时,生成效果也朝着更加精细化方向发展。 越来越多的“数字人”正在走入各行各业,不受空间、时间的限制,解放着人们的生产力。 来了!阿里云智能媒体服务正式推出:数字人形象和人声特征克隆模型的自助训练,一站式提供文本、语音驱动的仿真形象合成及视频终片创作的完整能力。 文末更有限时福利,让您的“数字分身”永久免费续期~ 形象、声音、生产力 首先,我们来看看如何定义一个好的数字人服务? 一是数字人的“形象”,无论是动作、表情、还是口型等需要具有高还原度的拟真效果,这也是数字人服务的基石; 二是数字人的“声音”,去僵硬、机器感,以同步拟真的声音,进一步提升数字人的生动感、完整度; 在拟真的形象与声音之上,三是能将数字人运用于视频、直播等场景化创作,让以技术驱动的“人”带来真正的生产力; 四是数字人与背景、前景等多类元素合成时,需要充分融合表达画面一致性,提升视觉细节精致度和画面感染力, 这更是最终数字人成品质量的关键。 数字人的「超级服务方案」 阿里云智能媒体服务的数字人,是整合仿真形象渲染、声音克隆和视频精编二创的一体化服务方案。 |「形」:数字人形象训练及渲染 通过采集模特特定场景下播报形象的视频素材,以文本、语音驱动经过算法训练的“数字人”,生成多语种、任意语料、带有丰富拟真表情和动作的数字人视频。 对于2D真人形象定制,我们提供规范的SOP录制手册,可依据手册轻松自助完成训练素材的录制、编辑和上传,实现拟真度极高的形象表达。 DEMO视频:https://v.youku.com/v_show/id_XNjAxOTM1NzM2OA==.html |「声」:人声克隆训练及渲染 当前人声克隆分为专业定制版、轻量定制版及基础版。 基础版在线可用,系统自动分配20句文案简单录制,覆盖故事、交互、导航三大细分场景,便捷快速复刻人声。通过用户上传的录音内容,30min即可捕捉关键声纹特征克隆人声,达到用户级娱乐效果。 轻量定制版(重点介绍)基于视频云多年深耕音视频算法,融合音质检测、音频降噪和数字克隆的多维度算法,基于15-30min有效音频,即可高保真还原音色。同时还可随着使用需求不同,指定音色情绪,满足不同应用场景的声音灵活适配。 人声克隆轻量定制版Demo: 原始训练声音(截取):https://v.youku.com/v_show/id_XNjAxOTM1NzU5Mg==.html 声音克隆结果:https://v.youku.com/v_show/id_XNjAyMjA1NTc0NA==.html |「效」:场景化视频抠除及背景融合 对于绿幕/实景视频,除了抠出内容边界清晰、自然无残漏的人像,还能指定抠出人像附属物,如:桌面、手持物品等。 实景抠图带附属物效果 即使数字人在不同光线及色彩环境下,也能自动将数字人与背景进行一致化融合处理,实现视频全片自然统一的超自然合成效果。 自动适配冷暖色调融合效果:https://v.youku.com/v_show/id_XNjAyMjA1NDA4MA==.html |「创」:丰富的衍生制作能力及精编二创 阿里云「云端智能剪辑」提供专业的音视频剪辑(多层级元素、专业字幕、转场过渡、特效滤镜)能力及完善的视频模版工具。 通过浏览器非线性编辑器或AE制作模版库,结合数字人自动化渲染,可实现数字人名片、数字人慕课等标准模版组合方案,满足短视频、教学视频、广告宣传等各类数字人视频制作的要求。 浏览器剪辑界面 |「互」:数字人直播实时互动 基于数字人直播及实时互动的标准场景,我们即将提供开箱即用的SaaS工具,从直播间装修、数字人脚本设定到互动方案及数字人响应内容预置,实现一键开播。 直播间不仅支持多个官方数字人形象,并支持自助训练数字人。 如下方视频所示,客户通过阿里云智能媒体服务进行数字人及人声克隆(轻量定制版)定制及视频合成,将其运用于法律、财经知识的重点解读。 客户案例示例:https://v.youku.com/v_show/id_XNjAyMjA2MDAzMg==.html “训”一个数字分身! 数字人自助训练定制,已上线阿里云「智能媒体服务」! 只需4步,即可“训”一个数字分身。 1️⃣ Step 1: 风格确认 ﹣ 2D仿真人|3D卡通人 ﹣ 性别确认、形象风格 ﹣ 视频成片调性、主播姿态设计 2️⃣ Step 2: 真人拍摄 ﹣ 绿幕(建议)或实景环境确认 ﹣ 按照操作手册自助录制 ﹣ 生成初版训练视频 3️⃣ Step 3: 内容预处理 ﹣ 美颜处理 ﹣ 抠图处理(平台也可自动扣图) ﹣ 生成终版训练视频 4️⃣ Step 4: 形象定制训练 ﹣ 形象渲染 ﹣ 生成形象code 「限时福利」,终身免费续期! 为了感谢您对数字人定制服务的关注与支持,我们重磅推出了一项“限时福利”,在活动有效期内发起定制数字人服务,即可享受终身免费续期的特权! 活动有效期到什么时间? 限时福利活动有效期为2023年11月30日24点前请在规定期内完成数字人定制任务提交操作。 该福利适用什么平台? 当前限时福利仅适用于通过阿里云智能媒体服务发起数字人定制的用户。 活动开始前已定制的数字人是否适用当前活动? 适用。只要在活动结束时间之前发起定制任务,均满足活动条件,自动享受福利特权。 欢迎加入官方答疑钉钉群咨询交流:31783668 福利页详情链接:https://www.aliyun.com/activity/cdn/avatar_free_renewal_activity?spm=5176.20960838.0.0.6df4305eCdx2Vm

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

MySQL慢查询(中):正确的处理姿势,你get到了吗?

我是架构精进之路,点击上方“关注”,坚持每天为你分享技术干货,私信我回复“01”,送你一份程序员成长进阶指南大礼包。 上篇回顾 继上篇:MySQL慢查询(上):你知道为啥会慢么? 在上一篇内容中,我们一起探索了这些内容: SQL执行过程 查询SQL为什么会慢 通过梳理 MySQL中的 SQL执行过程我们发现,任何流程的执行都存在其执行环境和规则,主要导致慢查询最根本的问题就是需要访问的数据太多,导致查询不可避免的需要筛选大量的数据。 如果将MySQL慢查询作为一个问题来拆解分析的话,上一篇算是问题分析,那今天来跟大家聊聊问题定位和问题解决。 本文主要内容包括: 1、如何定位慢查询问题 2、几种实用解决方案 废话不多说,直接开干~ 1、如何定位问题呢? 发现了慢查询之后,关于如何定位问题发生原因,最常用的方法就是利用EXPLAIN关键字模拟查询优化器执行查询SQL,从而知道MySQL是如何处理你的查询SQL,通过执行计划来分析性能瓶颈。 通常我们使用EXPLAIN,会得到如下下的执行计划信息: 关于各字段含义,大家可以通过检索自行了解,在此就不再过多赘述。 关于定位分析问题,关键看如下几点: 1)select_type 表示查询类型,用于区别普通查询、联合查询、子查询等复杂查询。 2)type 显示查询使用类型,从好到差依次为:system > const > eq_ref > ref > range > index > all 3)possible_keys 和 key 分别指可能应用的索引和实际应用的索引。 注意:查询中若使用了覆盖索引(select 后要查询的字段刚好和创建的索引字段完全相同),则该索引仅出现在key列表中。 4)rows 大致估算出找到所需记录所需要读取的行数(从效率上来讲,数值越小越好) 5)Extra 重要的额外信息。包含MySQL解决查询的详细信息,也是关键参考项之一。 2、几种实用解决方案 我们通过EXPLAIN关键字模拟查询优化器执行查询SQL,发现了慢查询问题原因,那看看如何才能有效解决呢? 推进几种较为实用的解决方案给大家。 2.1 优化数据结构 2.1.1 选择索引的数据类型 MySQL支持很多数据类型,选择合适的数据类型存储数据对性能有很大的影响。 通常来说,可以遵循以下一些指导原则: (1)越小的数据类型通常更好:越小的数据类型通常在磁盘、内存和CPU缓存中都需要更少的空间,处理起来更快。 (2)简单的数据类型更好:整型数据比起字符,处理开销更小,因为字符串的比较更复杂。在MySQL中,应该用内置的日期和时间数据类型,而不是用字符串来存储时间;以及用整型数据类型存储IP地址。 (3)尽量避免NULL:应该指定列为NOT NULL,除非你想存储NULL。在MySQL中,含有空值的列很难进行查询优化,因为它们使得索引、索引的统计信息以及比较运算更加复杂。你应该用0、一个特殊的值或者一个空串代替空值。 2.1.2 范式与反范式 范式化 范式化模型要求满足下面三大范式: 1)数据库表中每个字段只包含最小的信息属性,不能再进行细化分解; 2)(在满足1的基础上)模型含有主键,非主键字段依赖主键; 比如用户这个模型,它的主键是用户ID,那么用户模型其它字段都应该依赖于用户ID 如商品ID和用户没有直接关系,则这个属性不应该放到用户模型而应该放到“用户-商品”中间表。 3)(在满足2的基础上)模型非主键字段不能相互依赖。 订单表(订单编号,订购日期,顾客编号,顾客姓名,……) 初看该表没有问题,满足第二范式,每列都和主键列”订单编号”相关。 再细看你会发现“顾客姓名”和“顾客编号”相关,“顾客编号”和“订单编号”又相关,最后经过传递依赖,“顾客姓名”也和“订单编号”相关。 为了满足第三范式,应去掉“顾客姓名”列,放入客户表中。 反范式化 反范式化模型即不满足范式化的模型。主要是为了性能和效率的考虑适当的违反范式化设计要求,允许存在少量的数据冗余,即以空间换时间。 小结 可见一个良好而实用的数据模型往往是依赖于具体的需求场景的,在设计数据模型之前,仔细分析需求场景,不仅能提高效率,也能有效规避后期可能遇到的一些意外麻烦。 范式化设计和反范式化设计的优劣对比如下: 1、范式化可以尽量的减少数据冗余 2、范式化的更新操作比反范式化更快 3、范式化的表通常比反范式化的表要小 4、反范式化减少表的关联 5、反范式化相比范式化可以更好的对索引进行优化,例如使用覆盖索引。 关于数据库范式与反范式设计,详情可参考我之前的一篇文章:数据库范式与反范式设计,是一门艺术 2.2 应用索引策略 索引(MySQL中也被称为“键Key”),是存储引擎用于快速找到记录的一种数据结构。索引对于良好的性能非常关键,尤其当表中的数据量越来越大时,索引对性能的影响愈发重要(不恰当的索引对会随数据量增大时,性能急剧下降)。 举例如下情况: 假设数据库中一个表有10^6条记录,DBMS的页面大小为4K(约可存储100条记录)。 如果没有索引,查询将对整个表进行扫描,最坏的情况下,如果所有数据页都不在内存,需要读取10^4个页面,如果这10^4个页面在磁盘上随机分布,需要进行10^4次I/O,假设磁盘每次I/O时间为10ms(忽略数据传输时间),则总共需要100s(但实际上要好很多很多)。 如果对之建立B-Tree索引,则只需要进行log100(10^6)=3次页面读取,最坏情况下耗时30ms。这就是索引带来的效果。 了解了索引的优点之后,其实正确的创建和使用索引是实现高性能查询的基础。 可以利用B-Tree索引进行全关键字、关键字范围和关键字前缀查询,当然,如果想使用索引,必须保证按索引的最左边前缀(leftmost prefix of the index)来进行查询。 2.2.1 最左边前缀主要规则 匹配全值(Match the full value):对索引中的所有列都指定具体的值。例如,上图中索引可以帮助你查找出生于1960-01-01的Cuba Allen。 匹配最左前缀(Match a leftmost prefix):你可以利用索引查找last name为Allen的人,仅仅使用索引中的第1列。 匹配列前缀(Match a column prefix):例如,你可以利用索引查找last name以J开始的人,这仅仅使用索引中的第1列。 匹配值的范围查询(Match a range of values):可以利用索引查找last name在Allen和Barrymore之间的人,仅仅使用索引中第1列。 匹配部分精确而其它部分进行范围匹配(Match one part exactly and match a range on another part):可以利用索引查找last name为Allen,而first name以字母K开始的人。 仅对索引进行查询(Index-only queries):如果查询的列都位于索引中,则不需要读取元组的值。 由于B-树中的节点都是顺序存储的,所以可以利用索引进行查找(找某些值),也可以对查询结果进行ORDER BY。 当然,使用B-tree索引有以下一些限制: 查询必须从索引的最左边的列开始。关于这点已经提了很多遍了。例如你不能利用索引查找在某一天出生的人。 不能跳过某一索引列。例如,你不能利用索引查找last name为Smith且出生于某一天的人。 存储引擎不能使用索引中范围条件右边的列。例如,如果你的查询语句为WHERE lastname="Smith" AND firstname LIKE 'J%' AND dob='1976-12-23',则该查询只会使用索引中的前两列,因为LIKE是范围查询。 2.2.2 聚簇索引 聚簇索引保证关键字的值相近的元组存储的物理位置也相同(所以字符串类型不宜建立聚簇索引,特别是随机字符串,会使得系统进行大量的移动操作),且一个表只能有一个聚簇索引。因为由存储引擎实现索引,所以,并不是所有的引擎都支持聚簇索引。目前,只有solidDB和InnoDB支持。 InnoDB对主键建立聚簇索引。如果你不指定主键,InnoDB会用一个具有唯一且非空值的索引来代替。如果不存在这样的索引,InnoDB会定义一个隐藏的主键,然后对其建立聚簇索引。 2.3 查询缓存 MySQL查询缓存会保存查询返回的完整结果。当查询命中缓存,MySQL会立刻返回结果,而跳过了后续解析、优化以及执行阶段,会有效提升查询性能。 但是查询缓存不是银弹,它也会存在一些问题。 2.3.1 查询缓存注意事项 1)缓存情况严格 存在一些不确定函数情况无法使用查询缓存,如:NOW()、CURRENT_DATE() 等类似的函数; 超过 query_cache_size (设置查询缓存空间大小)的查询结果无法被缓存; 同时大小写敏感,只有字符串相等情况下查询SQL才使用相同缓存。 -- 不会使用同一个缓存select name from users where id = 1;SELECT name FROM users WHERE id = 1; 2)缓存易失效 假如缓存过查询结果,但是由于查询缓存设置内存不足,新缓存加入时MySQL会将某些缓存逐出,导致后续查询未命中。同时数据结构及数据修改,内存不足,缓存碎片都会导致缓存失效。 2.3.2 小结 查询缓存对应用程序完全透明,应用程序无需关心MySQL是通过查询缓存返回的还是实际执行返回的结果。但随着目前服务器性能越来越强,查询缓存被发现是一个影响服务器扩展性的因素,它很可能成为整个服务器的资源竞争点,大家采用生产环境开启应用时候一定要慎重考量。 2.4 重构查询方式 优化慢查询时候,我们可以转换下思路,我们的目标是找到一个更优的方法获取时间需要的结果,而不是一定从MySQL获取一模一样的结果集。重构查询的技巧很有必要。 2.4.1 复杂查询拆分 将一个复杂查询拆分多个简单查询,考虑是否需要将一个复杂查询拆分为多个简单查询。 实际开发过程中,大家往往会强调数据库层完成尽可能多的工作,这样做的初衷是认为网络通信、查询解析和优化是一件代价很高的事情,其实MySQL从设计上让连接和断开都很轻量级,同时在返回一个小查询结果方面很高效。况且目前网络速度也比之前快很多,无论是带宽还是延迟。 对于大查询我们要“分而治之”,将大查询切分成多个小查询。不过在一次查询能够胜任的情况下还拆成多个独立查询就不明智了。 例如:做数据库做10次查询,每次返回一行记录。 2.4.2 分解关联查询 将关联查询进行分解,对每一个表进行一次单表查询,然后将结果在应用程序中进行关联。 例如: SELECT *FROM usersLEFT JOIN orders ON orders.user_id = users.user_idLEFT JOIN goods ON goods.good_id = orders.good_idWHERE users.name = 'zhangsan'; 以上查询可以分解成下面的查询来代替: SELECT * FROM users WHERE users.name = 'zhangsan';SELECT * FROM orders WHERE orders.user_id = 103;SELECT * FROM goods WHERE goods.good_id IN (123, 456, 789); 为什么要这样做呢?看起来好像没有什么好处,而且返回数据结果也是一致的。实际上利用分解查询的方式来重构查询有很大的优势,主要表现为: 将查询分解后,执行单个查询可减少锁的竞争; 应用层做关联,更容易对数据库进行拆分,更易于做到高性能和可扩展; 减少冗余记录的查询(在应用层做关联,表示对某条记录应用只需要查询一次,而在数据库中做关联查询,则可能需要重复访问一部分数据。) 小结 MySQL慢查询问题细数起来,林林总总太多了,但行之有效的无外乎这几种: 优化数据结构 应用索引策略 查询缓存 重构查询方式 实践出真知,如果大家有任何其他好的解决方法可以留言与我交流,希望对你的工作有所帮助,谢谢! 闻道有先后,所有的技术成长无外乎不断的温习基础+实践锤炼,关注回复关键字【MySQL】,获取《高性能MySQL 第3版》PDF电子书,成就优秀的自己 ~ - END - 限于文章篇幅,同时为了大家更好的阅读体验,后面会连续产出系列文章: MySQL慢查询(下) 主要内容包括高性能查询难题优化内容点总结 最后,欢迎大家持续关注~ 作者:架构精进之路,专注软件架构研究,技术学习与个人成长,关注并私信我回复“01”,送你一份程序员成长进阶指南大礼包。 「技术架构精进」专注架构研究,技术分享 Thanks for reading! 本文分享自微信公众号 - 架构精进之路(jiagou_jingjin)。 如有侵权,请联系 support@oschina.cn 删除。 本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

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

FastDFS的配置、部署与API使用解读(1)Get Started with FastDFS

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/kese7952/article/details/82315001 版权声明:本文为博主原创文章,未经博主允许不得转载。合作请联系微信 sinosuperman。 https://blog.csdn.net/Poechant/article/details/6977407 转载请注明来自:诗商·柳惊鸿CSDN博客,原文链接:FastDFS的配置、部署与API使用解读(1)入门使用教程 1、背景 FastDFS是一款开源的、分布式文件系统(Distributed File System),由淘宝开发平台部资深架构师余庆开发。该开源项目的主页是 http://code.google.com/p/fastdfs 。可以通过fastdfs.sourceforge.net 下载。FastDFS论坛是 http://www.csource.org ,目前是指向 ChinaUnix 开源项目孵化平台的一个板块 FastDFS,网址为 bbs.chinaunix.net/forum-240-1.html 。 2、上传流程 我们可以通过 FastDFS 对文件的上传过程,来初步了解 FastDFS 的基本架构。首先客户端 client 发起对 FastDFS 的文件传输动作,是通过连接到某一台 Tracker Server 的指定端口来实现的,Tracker Server 根据目前已掌握的信息,来决定选择哪一台 Storage Server ,然后将这个Storage Server 的地址等信息返回给 client,然后 client 再通过这些信息连接到这台 Storage Server,将要上传的文件传送到给 Storage Server上。 3、架构简析 以上这段粗糙简单的描述,基本理清了 FastDFS 的上传过程。我们可以知道,FastDFS 是包括一组 Tracker Server 和 Storage Server 的。Tracker Server 与 Storage Server 之间不直接通信,其基本的信息由配置文件在系统启动加载时获知。多台 Tracker Server 之间保证了 Tracker 的分布式,Tracker Server 之间是对等的,防止了单点故障。 Storage Server 是分成多个 Group,每个 Group 中的Storage 都是互相备份的,也就是说,如果 Group1 有 Storage1、Storage2、Storage3,其容量分别是100GB、100GB、100GB,那么 Group1 的存储能力是 100GB,而不是 300GB,这就是互相备份的意思。进一步说,整个 Group 的存储能力由该组中该储能力最小的 Storage 决定。多个 Group 之间的存储方式,可以采用 round robin(轮训)、load balanced(负载均衡)或指定 Group 的方式。另一点相对于MS(Master-Slave)模式的优势,就是 Tracker Server 与 Master 是决然不同的,不仅 master 有上面可能提到的单点故障问题,而且 client 与 master 之间可能会出现瓶颈。但 FastDFS 架构中,Tracker Server 不会称为系统瓶颈,数据最终是与一个 available 的 Storage Server 进行传输的。 4、总结 简单总结一下,FastDFS的特点包括(1)高可靠性:无单点故障;(2)高吞吐量:只要 Group 足够多,数据流量是足够分散的。 5、三篇入门博文 FastDFS 还有一个特点,就是适用于小文件存储,因为 FastDFS 不回对文件进行分块。因为文件比较小(比如普通级别的图片类应用,文件最大就在几个MB的量级),一来没有必要分块,二来分块会加重服务器的工作量。但是,如果把 FastDFS 应用于大文件存储的场景,可能这一特点就会变成缺点。 以下这三篇是ITeye的一位博友关于 FastDFS 的部署、配置与测试的博文,写得简明扼要,我就不再冗余地写一篇了。 部署篇:http://soartju.iteye.com/blog/803477 配置篇:http://soartju.iteye.com/blog/803524 测试篇:http://soartju.iteye.com/blog/803548 转载请注明来自:诗商·柳惊鸿CSDN博客,原文链接:FastDFS的配置、部署与API使用解读(1)入门使用教程

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

云原生领域首本架构白皮书,你Get到了吗?

云栖号资讯:【点击查看更多行业资讯】在这里您可以找到不同行业的第一手的上云资讯,还在等什么,快来! 【导读】近日,由阿里云 20+ 位云原生技术专家共同编撰的《云原生架构白皮书》正式对外发布。作为业界第一本全方位构建云原生架构规划与实践全景图的白皮书,本书在详细阐述云原生架构定义的同时,完整展示云原生架构应用所需的演进路径与设计规则,旨在帮助企业更好地理解与应用云原生架构,助力企业数字化转型升级。 以下为 Serverless 章节内容: 随着以 Kubernetes 为代表的云原生技术成为云计算的容器界面,Kubernetes 成为云计算的新一代操作系统。面向特定领域的后端云服务(BaaS)则是这个操作系统上的服务 API,存储、数据库、中间件、大数据、AI 等领域的大量产品与技术都开始提供全托管的云形态服务,如今越来越多用户已习惯使用云服务,而不是自己搭建存储系统、部署数据库软件。 当这些 BaaS 云服务日趋完善时,Serverless 因为屏蔽了服务器的各种运维复杂度,让开发人员可以将更多精力用于业务逻辑设计与实现,而逐渐成为云原生主流技术之一。 技术特点 Serverless 计算包含以下特征: 全托管的计算服务,客户只需要编写代码构建应用,无需关注同质化的、负担繁重的基于服务器等基础设施的开发、运维、安全、高可用等工作; 通用性,结合云 BaaS API 的能力,能够支撑云上所有重要类型的应用; 自动的弹性伸缩,让用户无需为资源使用提前进行容量规划; 按量计费,让企业使用成本得有效降低,无需为闲置资源付费。 函数计算(Function as a Service)是 Serverless 中最具代表性的产品形态。它通过把应用逻辑拆分多个函数,每个函数都通过事件驱动的方式触发执行,例如当对象存储(OSS)中产生的上传 / 删除对象等事件,能够自动、可靠地触发 FaaS 函数处理,且每个环节都是弹性和高可用的,客户能够快速实现大规模数据的实时并行处理。同样的,通过消息中间件和函数计算的集成,客户可以快速实现大规模消息的实时处理。 目前函数计算这种 Serverless 形态在普及方面仍存在一定困难,例如: 函数编程以事件驱动方式执行,这在应用架构、开发习惯方面,以及研发交付流程上都会有比较大的改变; 函数编程的生态仍不够成熟,应用开发者和企业内部的研发流程需要重新适配; 细颗粒度的函数运行也引发了新技术挑战,比如冷启动会导致应用响应延迟,按需建立数据库连接成本高等。 针对这些情况,在 Serverless 计算中又诞生出更多其他形式的服务形态,典型的就是和容器技术进行融合创新,通过良好的可移植性,容器化的应用能够无差别地运行在开发机、自建机房以及公有云环境中;基于容器工具链能够加快解决 Serverless 的交付。云厂商如阿里云提供了弹性容器实例(ECI)以及更上层的 Serverless 应用引擎(SAE),Google 提供了 CloudRun 服务,这都帮助用户专注于容器化应用构建,而无需关心基础设施的管理成本。此外 Google 也开源了基于 Kubernetes 的 Serverless 应用框架 Knative。 相对函数计算的编程模式,这类 Serverless 应用服务支持容器镜像作为载体,无需修改即可部署在Serverless 环境中,可以享受到 Serverless 带来的全托管免运维、自动弹性伸缩、按量计费等优势。下面是传统的弹性计算服务、基于容器的 Serverless 应用服务和函数计算的对比: 常见场景 近两年来 Serverless 近年来呈加速发展趋势,用户使用 Serverless 架构在可靠性、成本和研发运维效率等方面获得显著收益。小程序 /Web/Mobile/API 后端服务 在小程序、Web/Moible 应用、API 服务等场景中,业务逻辑复杂多变,迭代上线速度要求高,而且这类在线应用,资源利用率通常小于 30%,尤其是小程序等长尾应用,资源利用率更是低于 10%。Serverless 免运维,按需付费的特点非常适合构建小程序 /Web/Mobile/API 后端系统,通过预留计算资源 + 实时自动伸缩,开发者能够快速构建延时稳定、能承载高频访问的在线应用。在阿里内部,使用 Serverless 构建后端服务是落地最多的场景,包括前端全栈领域的 Serverless For Frontends,机器学习算法服务,小程序平台实现等等。 大规模批处理任务 在构建典型任务批处理系统时,例如大规模音视频文件转码服务,需要包含计算资源管理、任务优先级调度、任务编排、任务可靠执行、任务数据可视化等一系列功能。如果从机器或者容器层开始构建,用户通常使用消息队列进行任务信息的持久化和计算资源分配,使用 Kubernetes 等容器编排系统实现资源的伸缩和容错,自行搭建或集成监控报警系统。而通过 Serverless 计算平台,用户只需要专注于任务处理逻辑的处理,而且 Serverless 计算的极致弹性可以很好地满足突发任务下对算力的需求。 通过将对象存储和 Serverless 计算平台集成的方式,能实时响应对象创建、删除等操作,实现以对象存储为中心的大规模数据处理。用户既可以通过增量处理对象存储上的新增数据,也可以创建大量函数实例来并行处理存量数据。 基于事件驱动架构的在线应用和离线数据处理 典型 Serverless 计算服务通过事件驱动的方式,可以广泛地与云端各种类型服务集成,用户无需管理服务器等基础设施和编写集成多个服务的“胶水”代码,就能够轻松构建松耦合、基于分布式事件驱动架构的应用。 通过和事件总线的集成,无论是一方 BaaS 云服务,还是三方的 SaaS 服务,或者是用户自建的系统,所有事件都可以快速便捷地被函数计算处理。例如通过和 API 网关集成,外部请求可以转化为事件,从而触发后端函数处理。通过和消息中间件的事件集成,用户能快速实现对海量消息的处理。 开发运维自动化 通过定时触发器,用户用函数的方式就能够快速实现定时任务,而无须管理执行任务的底层服务器。通过将定时触发器和监控系统的时间触发器集成,用户可以及时接收机器重启、宕机、扩容等 IaaS 层服务的运维事件,并自动触发函数执行处理。 技术关注点 计算资源弹性调度 为了实现精准、实时的实例伸缩和放置,必须把应用负载的特征作为资源调度依据,使用“白盒”调度策略,由Serverless 平台负责管理应用所需的计算资源。平台要能够识别应用特征,在负载快速上升时,及时扩容计算资源,保证应用性能稳定;在负载下降时,及时回收计算资源,加快资源在不同租户函数间的流转,提高数据中心利用率。因此更实时、更主动、更智能的弹性伸缩能力是函数计算服务获得良好用户体验的关键。通过计算资源的弹性调度,帮助用户完成指标收集、在线决策、离线分析、决策优化的闭环。 在创建新实例时,系统需要判断如何将应用实例放置在下层计算节点上。放置算法应当满足多方面的目标: 容错:当有多个实例时,将其分布在不同的计算节点和可用区上,提高应用的可用性。 资源利用率:在不损失性能的前提下,将计算密集型、I/O 密集型等应用调度到相同计算节点上,尽可能充分利用节点的计算、存储和网络资源。动态迁移不同节点上的碎片化实例,进行“碎片整理”,提高资源利用率。 性能:例如复用启动过相同应用实例或函数的节点、利用缓存数据加速应用的启动时间。 数据驱动:除了在线调度,系统还将天、周或者更大时间范围的数据用于离线分析。离线分析的目的是利用全量数据验证在线调度算法的效果,为参数调优提供依据,通过数据驱动的方式加快资源流转速度,提高集群整体资源利用率。 负载均衡和流控 资源调度服务是 Serverless 系统的关键链路。为了支撑每秒近百万次的资源调度请求,系统需要对资源调度服务的负载进行分片,横向扩展到多台机器上,避免单点瓶颈。分片管理器通过监控整个集群的分片和服务器负载情况,执行分片的迁移、分裂、合并操作,从而实现集群处理能力的横向扩展和负载均衡。 在多租户环境下,流量隔离控制是保证服务质量的关键。由于用户是按实际使用的资源付费,因此计算资源要通过被不同用户的不同应用共享来降低系统成本。这就需要系统具备出色的隔离能力,避免应用相互干扰。 安全性 Serverless 计算平台的定位是通用计算服务,要能执行任意用户代码,因此安全是不可逾越的底线。系统应当从权限管理、网络安全、数据安全、运行时安全等各个维度全面保障应用的安全性。轻量安全容器等新的虚拟化技术实现了更小的资源隔离粒度、更快的启动速度、更小的系统开销,使数据中心的资源使用变得更加细粒度和动态化,从而更充分地利用碎片化资源。 以上内容出自阿里云出品的《云原生架构白皮书》。 本报告共分为七大章节,涵盖为什么需要云原生架构、云原生架构定义、主要云原生技术、阿里巴巴云原生架构设计、阿里云云原生产品介绍、云原生架构实践案例、云原生架构未来发展趋势几部分,详细阐述了云原生领域的整体落地应用及未来发展趋势。 【云栖号在线课堂】每天都有产品技术专家分享!课程地址:https://yqh.aliyun.com/live 立即加入社群,与专家面对面,及时了解课程最新动态!【云栖号在线课堂 社群】https://c.tb.cn/F3.Z8gvnK 原文发布时间:2020-08-03本文作者:CSDN云计算本文来自:“CSDN云计算”,了解相关信息可以关注“CSDN云计算”

资源下载

更多资源
优质分享App

优质分享App

近一个月的开发和优化,本站点的第一个app全新上线。该app采用极致压缩,本体才4.36MB。系统里面做了大量数据访问、缓存优化。方便用户在手机上查看文章。后续会推出HarmonyOS的适配版本。

腾讯云软件源

腾讯云软件源

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

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

用户登录
用户注册