# 开源文化对360企业安全的影响
摘自 InfoQ [360的开源软件使用以及开源文化构建经验](http://www.infoq.com/cn/articles/360-open-source-software-and-culture-build-experience)
奇虎360企业安全从2011年到2015年,经历了几次服务端架构的变迁。从一开始的软件自研到最后的全部使用开源软件,360企业安全部真切体会到了开源软件带来的好处。另外,360也通过各种各样的方式来构建自己开放、透明、平等的企业文化。InfoQ编辑采访了奇虎企业安全高级工程师温铭,听他分享了360内部的开源软件实践经验以及开源文化构建经验。同时,温铭还将在ArchSummit全球架构师峰会上分享题为《开源文化对360天擎架构演进的影响》的演讲,敬请关注。
> InfoQ:能分阶段介绍下360企业安全的服务端架构的演进情况吗?
360企业安全服务端的架构演进主要分为三个阶段。第一个阶段是以自己开发的组件为主。我们用C++自己写了一个简易的Web Server,并在此基础上面衍生的一系列工具。页面的开发,我们没有使用成熟的PHP框架,而是自己写了个路由。这一阶段产生的问题就是基础组件不稳定,跟不上产品功能的快速迭代,而不稳定的产品,企业用户也不能接受。开发付出了很多努力,但一直没有找到适当的节奏。
后面有几个开发的同事觉得要跳出这个糟糕的循环,于是就在新模块的开发中引入了OpenResty和Yii,并和自研的组件并存。这样带来的明显好处是效率的提升,开发有精力来完成了前后端分离,QA也从完全的黑盒测试中脱身,搭建了服务端的自动化测试和性能测试。这些改变为后面重构打下了坚实的基础。
在第三个阶段,我们重构了产品,并统一了服务端的技术架构,同时相关的功能组件全部换用成熟的开源软件搭建。比如我们使用OpenResty来搭建整个服务端,周边工具用Python和Go来完成,报表和数据分析采用ElasticSearch。这样开发就可以更专注于产品功能实现和开源软件的深入学习,而不用担心基础组件的稳定性。
> InfoQ:你提到,一开始的时候你们的开发人员都在自己『造轮子』,那这样的方式有什么问题?在自研和开源软件之间,你认为应该如何选择?
温铭:很多时候,『造轮子』的原因是开发人员没有找到合适的开源软件,或者在技术方面自视过高。盲目的自己从头开发组件,时间成本、稳定性以及后续的维护都是问题。我认为『造轮子』的前提是,现有的成熟开源软件不满足你的需求。比如360云查杀对性能要求非常高,而当时没有开源软件符合需求,所以我们就在LevelDB的基础上面开发自己的Key-Value数据库。而对于大部分的服务端开发来说,开源软件足以应付相关需求。
> InfoQ:开源软件的选型上,你有什么好的经验吗?
温铭:现在开源软件发展非常快,新技术层出不穷,在技术选型的时候,你会面对很多的选择。不管使用什么开源软件,在服务端的架构层面,你都需要做到各个组件像乐高积木一样,没有耦合并且可以方便的进行更换。在你产品的第一个的版本里面,最好选择成熟稳定、自己团队熟悉的开源软件,而不是性能最好的,因为这时候你需要快速的出产品和快速迭代,性能并不是最重要的;在随后的版本中,你可以通过性能测试的各项数据,来决定使用哪个开源软件。除了性能的考虑之外,开源软件自身的发展也需要考虑:对开发者是否友好、修复bug的速度、版本迭代的周期等。
> InfoQ:开源软件的使用过程中,经常会涉及到需要修改开源软件的代码。那在内部版本和社区版本之间,你们是如何同步的,有什么好的经验吗?
温铭:360企业安全服务端有一个特殊的产品需求,是其它产品的服务端开发不会遇到的,就是需要支持Windows平台。因为很多企业还是希望软件运行在Windows上面。所以我们会对一些开源软件进行修改,以增加对Windows平台的支持。我们刚开始的做法是下载源代码,然后修改,但造成的问题是没法快速跟进开源软件版本的更新,也没法把修改的代码回馈到社区。现在我们会fork,然后把改动pull request向社区来回馈代码,同时要有完善的测试案例和文档,代码要符合软件本身的编码风格。
> InfoQ:你怎么看开源文化?360是如何构建开源文化的?
温铭:360在GitHub上面开源了多个自己开发的软件,公司内部有技术评级以及定期的技术嘉年华,鼓励工程师主动分享技术并参与到开源软件中去。在技术团队中,透明和平等的文化,最适合各种技术的成长。我们团队有一个不成文的规定:AKA(all know all)。比如在技术选型上,我们会出一个大概的架构,然后发给所有开发讨论,由于我们是一个大杂烩的技术团队,有人说“PHP是最好的语言”,有人是Python的粉丝,还有人推崇Go,还有人坚守Windows平台,所以各种讨(chao)论(jia)后才确定最后的选型。
> InfoQ:要使用开源软件,是不是需要团队成员对这些开源软件有足够的了解?
温铭:即使不去修改开源软件的代码,团队成员也需要对这些软件的内部实现有深入的了解,才能用到适合的场合以及做参数的调整。我们每周会有定期的技术分享和code review,来保证团队每个人都知道团队使用了哪些技术,如何更好使用这些技术。
> InfoQ:团队在参与开源软件方面,你有什么好的经验可以分享?
温铭:最重要的是要团队成员有主动性和热情参与其中。并不是贡献了patch才算参与到开源软件中,在实际的开发中解决了问题,总结分享出来,也是一种方式。我们团队正在GitBook上面写关于OpenResty和ElasticSearch的书,分享我们的一些实践。这也是一种参与开源的方式。
受访嘉宾介绍
温铭,一直在互联网安全公司从事高性能服务端的开发和架构,用各种技术手段打击木马传播和互联网欺诈。目前在奇虎用互联网技术帮助企业提高安全防护。
- 序
- Lua 入门
- Lua简介
- Lua环境搭建
- 基础数据类型
- 表达式
- 控制结构
- if/else
- while
- repeat
- for
- break,return
- Lua函数
- 函数的定义
- 函数的参数
- 函数的返回值
- 函数回调
- 模块
- String库
- Table库
- 日期时间函数
- 数学库函数
- 文件操作
- 元表
- 面向对象编程
- FFI
- 下标从1开始
- 局部变量
- 判断数组大小
- 非空判断
- 正则表达式
- 不用标准库
- 虚变量
- 函数在调用代码前定义
- 抵制使用module()函数来定义Lua模块
- 点号与冒号操作符的区别
- Nginx
- Nginx 新手起步
- location 匹配规则
- if 是邪恶的
- 静态文件服务
- 日志服务
- 反向代理
- 负载均衡
- 陷阱和常见错误
- 环境搭建
- Windows平台
- CentOS平台
- Ubuntu平台
- Mac OS X平台
- Hello World
- 简单API Server框架
- 获取Nginx内置绑定变量
- LuaRestyRedisLibrary
- select+set_keepalive组合操作引起的数据读写错误
- redis接口的二次封装(简化建连、拆连等细节)
- redis接口的二次封装(发布订阅)
- pipeline压缩请求数量
- script压缩复杂请求
- LuaCjsonLibrary
- json解析的异常捕获
- 稀疏数组
- 空table编码为array还是object
- 跨平台的库选择
- PostgresNginxModule
- 调用方式简介
- 不支持事务
- 超时
- 健康监测
- SQL注入
- LuaNginxModule
- 执行阶段概念
- 正确的记录日志
- 热装载代码
- 阻塞操作
- 缓存
- sleep
- 定时任务
- 禁止某些终端访问
- 请求返回后继续执行
- 调试
- 调用其他C函数动态库
- 我的lua代码需要调优么
- 变量的共享范围
- 动态限速
- shared.dict 非队列性质
- 如何添加自己的lua api
- 正确使用长链接
- 如何引用第三方resty库
- 典型应用场景
- LuaRestyDNSLibrary
- 使用动态DNS来完成HTTP请求
- 缓存失效风暴
- 测试
- 单元测试
- API测试
- 性能测试
- 持续集成
- 灰度发布
- Web 服务
- API的设计
- 数据合法性检测
- 协议无痛升级
- 代码规范
- 连接池
- C10K编程
- TIME_WAIT问题
- 与Docker使用的网络瓶颈
- 火焰图
- 什么时候使用
- 显示的是什么
- 如何安装火焰图生成工具
- 如何定位问题
- 开源文化对360企业安全的影响