跳转到主要内容
dustise 提交于 7 May 2014

简介

Drupal的弹性在现存CMS中名列前茅。

本书在五个方面为建立和管理Drupal站点提供了最佳实践。

Acquia的咨询团队在对大量的Drupal站点进行审计后,识别出一系列的错误模式,本书中,读者将从这一系列经验中获益良多。

  • 架构:内容结构规划,显示规划以及功能规划。
  • 安全:如何避免特定类型的攻击,保护站点。
  • 性能:性能分析工具,常用站点优化方法,如何避免缓存问题。
  • 基础架构:软件栈最佳实践,包括Varnish,Memcached等。
  • 维护:站点整个生命周期中的最佳实践,包括开发,部署以及维护阶段的内容。

本书假设用户能够熟练架设Drupal站点,熟悉PHP以及Drupal相关例如Hook和MySQL数据库的开发技术。

架构:内容

内容是站点的灵魂,是站点存在的根本。确定内容结构是网站架构的第一步。

最佳实践

对内容结构进行规划,包含Field以及内容类型。清晰的内容架构也是良好性能,用户体验以及运行维护的有力保障。(这部分和显示架构有点重复,因为Views的基础就在于内容类型)。

  • 错误:过多的内容类型。
  • 后果:对内容编辑人员造成干扰。
  • 举例:几乎一致的两个内容类型:“文章”和“新闻”。
  • 对策:对内容进行规范化管理,增强复用。

  • 错误:为每个内容类型新建Field。

  • 后果:降低性能,浪费资源。
  • 举例:为学校所在城市和教师所在城市建立两个不同的Field。
  • 对策:规范化使用Field,并尽可能重用。可以在http://site.url/admin/reports/fields查看Field的相关报告。

  • 错误:没有Node的内容类型。

  • 后果:无用的内容类型增加了不必要的复杂度。
  • 对策:建站初期要慎重考虑内容类型,利用内容过滤功能来鉴别并删除无用的内容类型。

架构:展示

强有力的内容展示功能是Drupal的重要组成部分,展示架构包含Views, Panels以及Context模块。

最佳实践

好的展示架构设计的一个重要标志就是:能够轻松的修改网站的观感。

  • 对展示架构进行规划,只在必要的时候进行内容渲染。
  • 尽量的优化和重用。
  • 展示和逻辑分离。
  • 在一个经过仔细学习研究的稳定的基主题基础上进行开发。

  • 错误:每个列表一个View。

  • 举例:伦敦、巴黎以及里斯本的工作,使用三个View。
  • 对策:新建View之前需要进行分析,看是否可以使用现有View来完成,使用Contextual Filters来通过指定参数渲染不同的列表。

  • 错误:在数据库或者模板文件中保存PHP代码或者其他业务逻辑。

  • 举例:利用PHP代码来确定比赛分数Block是否显示。
  • 对策:编写一个PHP逻辑,在Module或者Theme preprocess函数中调用Web Service或者SQL查询。

推荐工具

  • Theme Developer模块:利用这个模块,可以看到鼠标移过的各个区域是由哪个模板渲染而来的。

架构:功能

最佳实践

  • 保持站点轻盈,尽可能少的使用代码和模块来实现功能。
  • 优先使用已发布模块而不是自行开发。
  • 努力成为关键模块的专家,例如Views和Panels。
  • 遵循Drupal代码规范。
  • 对站点进行周期性的评估。

  • 错误:太多模块,激活200多个模块意味着需要进行分析,来确定是否所有模块都是必要的。

  • 举例1:原计划包含多语言,但是完工时仅支持英文,所有多语言相关的模块却都被激活。
  • 对策:周期性的评估网站,禁用,反安装并删除无用模块。

  • 错误:太多角色,难于进行管理和安全检查。

  • 举例:原计划中包含大量角色,但是多数都没用过。尤其是试图将角色和现实工作岗位进行匹配的过程中,会发现不同角色之间的重合情况。
  • 对策:评估站点的角色和权限,整理角色和权限的包含关系,整合功能角色。

  • 错误:自行编写已经在公开模块中实现过的代码。

  • 举例:开发自定义模块用于发送电子邮件给管理员。
  • 对策:这种情况下,经过良好测试的Webform模块也提供了该功能,同时还具有更大弹性。开发自定义代码之前,请确定没有任何合适的模块已经实现了你需要的功能。

  • 错误:入侵式修改公开模块或核心。这一行为的后果很难预测,对更新造成障碍。

  • 对策:如果公开模块或核心不能满足你的需要,创建一个新模块,使用钩子来实现你需要的行为。对现有站点,可以使用Acquia Insight或者Hacked!模块来查看是否存在这种入侵情况(参见推荐工具)。

  • 错误:错误的使用Hook或者Drupal API。

  • 举例1:为一个仅在首页生效的功能,使用了Hook_init,然而这个钩子会在每个页面执行。
  • 举例2:在代码中硬编码nid, tid或者vid,这使得一旦这些内容将来发生变化,可能会产生很难定位的错误。
  • 对策:开始写代码之前要慎重,在Drupal.org的API文档中查找合适的钩子及其用法。

推荐工具

  • Simplytest.me:在这个站点,简单的输入一个模块名称,站点就会生成一个限时使用30分钟的Drupal实例供测试。
  • Hacked!模块:这个模块会扫描Drupal的安装情况,包含公开的模块和主题,来判断这些内容是否被修改过。同Diff Module协同使用的话,结果页面会明确展示被改动过的行,这一模块千万不要使用在生产环境。
  • Acquia Insight我们的服务和Hacked!模块的扫描过程类似,不过还提供额外的站点配置和安全检查。

安全

好的安全设置能够在黑客的攻击之下保护站点。如果使用得当,Drupal具有很好的内置安全性。

最佳实践

从开始配置站点的那一刻起,安全问题随时都可能产生,对配置活动进行计划,以保证只有可信用户才能使用可能造成安全问题的权限。

  • 保证站点使用的核心和模块的更新。你可能不会选择一些对你站点无用的修复和增强,然而安全更新一定要第一时间进行跟进。Drupal.org的安全通告是一个获取更新的好办法。
  • 使用强密码。密码经常是站点被攻陷的最大原因。使用Password Policy模块可以为用户设置的密码设置一套约束。管理员也可以设置密码失效时间。
  • 限制文件上传以及文件类型。只允许可信用户上传,限制文件类型。在upload field中检查权限并指定文件类型。
  • 使用Acquia Insight和Security Review模块。Security Review模块会分析你的站点配置,并提供修复方法报告。这一模块只应该在开发和测试站点使用,在生产环境则应该禁用并删除。Acquia Insight还提供了更多的站点和安全检查项目。

针对自有代码的攻击防范

下面讲了三种最常见的针对自有代码攻击和防范。

防范SQL注入

  • 错误:在代码中直接使用MySQL查询而不是使用API。
  • 举例:这段代码

db_query("select * from table where id=$_GET[‘id’]");

可能在如下的访问中出现问题:

example .com/index .php?id=1 union select * from users

防范XSS-跨站脚本

  • 错误: 在没有检查的情况下,显示访问者的(输入)参数,使得访问者能够将客户端脚本注入他人浏览的页面。
  • 举例

<?php echo "Your number is " . $_GET['id']; ?>

允许攻击者访问

Index .php?id=<script>alert ("UAAAT??");</script>

  • 对策:在渲染之前需要对所有用户输入进行清理和过滤。

防范CSRF-跨站点请求伪造

  • 错误:包含百分号的网址,或者直接提交Form数据。Form的Http Post可能来自任何地方,而不只是你的站点。
  • 对策:使用Drupal的Form API,他会在每个Form中插入一个Token。在受保护的URL渲染过程中,要么使用Form API,要么在URL中嵌入Token,在响应代码中来检验是否存在有效的Token。参考资料

性能

性能在用户体验中是至关重要的一环。一个运行缓慢的站点,不论功能多么强大,都会将用户拒之门外。

最佳实践

性能优化要做的第一件事就是分析网站的业务,接下来根据运行情况进行最大程度的优化,最后是缓存。

分析工具

优化-一般问题

  • 无索引的复杂查询占用了过多时间。
  • 过于频繁的调用某些功能。
  • 无用Module却保持在激活状态。
  • 没有配置Cron。(Cron配置)。
  • 使用了缺省的Views分页,这一功能在查询时会附加一次COUNT查询。Views LitePager能够避免这一损耗。
  • Drupal 7缺省使用数据库进行日志记录(dblog),错误信息会很快的填满你的数据库。一个常用的方法是用syslog代替dblog,不过这一方法会使得日志不易访问。另外可以修改PHP的配置,减少notice和warning的输出。
  • 使用Fast 404模块来提供静态的404页面,避免无意义的Drupal bootstrap过程。
  • 没有进行CSS和JavaScript聚合,参见[如何开启CSS和JavaScript聚合](https://docs.acquia.com/cloud/performance#css-js)。

缓存-常见错误

  • 无缓存原则:不去花时间了解内容的缓存方式(每用户,每组,每角色等)是最恶劣的错误。
  • 过于频繁的清空缓存。
  • 缓存级别过低:例如应该使用Views缓存代替Block或Panels Pane缓存。
  • 使用超出需求的过分复杂的缓存策略。

推荐工具

基础设施

基础设施包含站点的运行技术栈,包括服务器、数据库以及其他软件例如Varnish或Memcached,这些设施是用户体验的基本保障。在项目初始就应进行基础设施的规划,尽量保证开发环境的一致性,能够有效的降低项目上线风险。对于多环境的配置能力以及可靠的灾难恢复措施也是重要的决策内容。下面是一些最常见的错误。

最佳实践

  • 正确的规划容量,太大太小都是错误的。
  • 瓶颈可能存在于硬件,也可能存在于进程独占的内容。应该对日志中的错误进行分析,并为流量的增长和爆发做好准备。网站性能取决于最慢的组件,因此应集中目标于此。
  • 无论内部还是外部攻击,都是需要防范的。

正确的规划容量

  • 错误:硬件容量足够,但缺乏配置。
  • 举例:数据库服务器具有48G的内存,但是InnoDB缓存仅设置了1G。
  • 对策:检查所有配置内容,利用工具对数据库进行分析。

提高Varnish命中率

  • 错误:错误的配置导致流量穿过Varnish直接命中Web服务器。
  • 对策:检查响应头,确认期望被缓存的页面的确来自缓存,确认没有设置不必要的Session变量。

避免暴露不必要的服务

  • 错误:远程连接访问数据库,Memcached或者Solr。
  • 举例:假设一个外部防火墙来提供保护,没有将Memcached服务器设置到IPTable的保护列表中。
  • 对策:50-70%的攻击来自内部,禁止数据库、Memcached或者Solr的远程访问,在每次基础设施发生变更的时候都需要再次确认访问策略。

推荐工具

  • mysqltuner.pl或者MYSQLTuner,是一个Perl脚本,可以从Github下载,这一工具将查询当改签配置并分析MySQL的安装状态,并提供一些基础的性能建议。
  • Infrastructure workshop:对于使用自有基础设施而非第三方维护例如Acquia托管的,不熟悉Drupal或LAMP体系的团队很有用。
  • 《Drupal多站点基础设施》提供了更多的多站点相关配置内容。

维护

一个网站的生命周期从策划开始,到关闭为止。这一周期包含三个不同的阶段:开发,发布以及维护。在站点上线之后,站点的成功直接依赖于团队的网站维护能力。

最佳实践

  • 保持代码的版本管理。
  • 为站点的不同环节(开发、测试、准生产等等)提供隔离环境,并保持更新。
  • 周期性检查日志,包含Apache, Drupal以及MySQL等。
  • 周期性的检查和评估基础设置,并对未来趋势进行预估。

利用版本管理进行可靠的协作

  • 错误:不使用版本控制。
  • 举例:偶尔把代码拷贝到备份文件夹作为版本控制的手段。
  • 对策:使用版本控制系统,目前Git在Drupal开发中是最流行的,不过其他系统也一样可以。另外要保证每次提交都附加有意义的提交说明,以此来保证你的合作者能够理解你的变更。

保持版本库的合理使用

  • 错误:在版本管理中保存无关文件。
  • 举例:图形文件,假期照片或者数据库备份。
  • 对策:尽量保证版本仓库整洁,并尽可能缩小尺寸。

以版本控制进行部署

  • 错误:利用FTP上传文件的方式进行发布。
  • 对策:发布行为必须以版本控制系统为源头。

安全保障

  • 错误:生产环境安全设置不足。
  • 举例:所有开发人员都可以从生产环境获取快照并安装到自己的电脑上。
  • 对策:只允许开发人员访问开发和准生产环境,只有最受信任的用户可以访问生产环境。

尽量保持在近似生产的环境上进行测试

  • 错误:开发或准生产环境过期,或者缺失部分功能。
  • 举例:因为其他环境数据过期,或者缺乏对某些必要服务的网络连接,导致必须从生产环境上发起测试。
  • 对策:尽可能让测试环境和生产环境保持一致。以此来保证从测试和生产环境之间进行迁移之后还能保持工作。

保持站点更新

  • 错误:站点使用过期的核心或模块。
  • 对策:尽可能的保持核心和模块的及时更新。

结论

网站是一个生命体,随着时间推移而不断发生变化,需要经常检查所有日志来确定当前的情况,你会不断发现增强或保护网站的新方法。对网站各方面进行周期性的检查是必须的措施。

保障一个大型Drupal网站运行是一个挑战,如果你能够遵循上述的最佳实践并避免上文列出的错误,你会让网站平顺运行,让老板开心,也不是那么难。

Drupal 版本