﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-快乐的天空-文章分类-学习</title><link>http://www.cppblog.com/HappySky2046/category/19028.html</link><description>时间来得快，去得也快</description><language>zh-cn</language><lastBuildDate>Sat, 19 Oct 2013 14:51:38 GMT</lastBuildDate><pubDate>Sat, 19 Oct 2013 14:51:38 GMT</pubDate><ttl>60</ttl><item><title>Premake 中的prebuildcommands</title><link>http://www.cppblog.com/HappySky2046/articles/203823.html</link><dc:creator>探路者</dc:creator><author>探路者</author><pubDate>Sat, 19 Oct 2013 14:31:00 GMT</pubDate><guid>http://www.cppblog.com/HappySky2046/articles/203823.html</guid><wfw:comment>http://www.cppblog.com/HappySky2046/comments/203823.html</wfw:comment><comments>http://www.cppblog.com/HappySky2046/articles/203823.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/HappySky2046/comments/commentRss/203823.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/HappySky2046/services/trackbacks/203823.html</trackback:ping><description><![CDATA[<p style="margin: 0px 0px 14px; font-family: Arial; background-color: #ffffff;">Premake4还有一个比较好用的特性，可以直接用 **/*.cpp 指定项目包含所有目录下的cpp文件，而不用单个指定。这样每次增加一个文件不用老等编译了才想起来忘记了增加文件到配置中。算是给懒人的一个福利吧。</p><p style="margin: 0px 0px 14px; font-family: Arial; background-color: #ffffff;">当然，Premake4也有自己的缺陷，目前还不支持自定义规则，所以如果项目中有用到什么自动生成源文件的特性就比较麻烦了，比如这次说到的protobuf要用protoc编译.proto文件生成.pb.cc和.pb.h文件，另外QT也有类似的需求，就我之前某项目中，也使用了tolua++生成过c++的lua接口文件。</p><p style="margin: 0px 0px 14px; font-family: Arial; background-color: #ffffff;">但是，Premake4虽然还不支持自定义规则，但是总算有一个prebuildcommands可以用，于是研究了一下，自制了一个.proto文件的"编译规则":</p><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; background-color: #ffffff;">function protobufs(pat)<br />  local list = {}<br />  if type(pat) == "string" then<br />    list[1] = pat;<br />  elseif type(pat) == "table" then<br />    list = pat;<br />  end<br />  local proj = project();<br />  for _,pat in ipairs(list) do<br />    local protofiles = os.matchfiles(pat);<br />    for _,protofile in ipairs(protofiles) do<br />      local basename = path.getbasename(protofile);<br />      local sourcedir = proj.basedir.."/"..path.getdirectory(protofile);<br />      local sourcefile = proj.basedir.."/"..protofile;<br />      local targetdir = "$(OBJDIR)/proto/"..path.getdirectory(protofile);<br />      local targetfile = targetdir.."/"..basename..".pb.cc";<br />      prebuildcommands {<br />        "@mkdir -p "..targetdir,<br />        "@test "..sourcefile.." \\\n"<br />        .."\t\t\t -ot "..targetfile.." || \\\n"<br />        .."\t\t( echo protoc "..protofile.." &amp;&amp; \\\n"<br />        .."\t\tprotoc --cpp_out "..targetdir.."\\\n"<br />        .."\t\t\t"..sourcefile.."\\\n"<br />        .."\t\t\t".." -I"..sourcedir.." ) \\\n"<br />      }<br />      files {<br />        path.join(targetdir, basename..".pb.h"),<br />        path.join(targetdir, basename..".pb.cc"),<br />      }<br />      includedirs { targetdir }<br />    end<br />  end<br />end</pre><p style="margin: 0px 0px 14px; font-family: Arial; background-color: #ffffff;">使用方法呢，就是把上面的代码保存到protobuf.lua里面，然后在premake4.lua最开始的时候，调用</p><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; background-color: #ffffff;">dofile "protobuf.lua"</pre><p style="margin: 0px 0px 14px; font-family: Arial; background-color: #ffffff;">然后在项目定义的时候，使用</p><pre style="margin-top: 0px; margin-bottom: 0px; margin-left: 22px; background-color: #ffffff;">protobufs { "**/*.proto" }</pre><p style="margin: 0px 0px 14px; font-family: Arial; background-color: #ffffff;">就可以了。</p><img src ="http://www.cppblog.com/HappySky2046/aggbug/203823.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/HappySky2046/" target="_blank">探路者</a> 2013-10-19 22:31 <a href="http://www.cppblog.com/HappySky2046/articles/203823.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Node.js的游戏服务器框架pomelo</title><link>http://www.cppblog.com/HappySky2046/articles/195992.html</link><dc:creator>探路者</dc:creator><author>探路者</author><pubDate>Tue, 04 Dec 2012 15:36:00 GMT</pubDate><guid>http://www.cppblog.com/HappySky2046/articles/195992.html</guid><wfw:comment>http://www.cppblog.com/HappySky2046/comments/195992.html</wfw:comment><comments>http://www.cppblog.com/HappySky2046/articles/195992.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/HappySky2046/comments/commentRss/195992.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/HappySky2046/services/trackbacks/195992.html</trackback:ping><description><![CDATA[<p style="font-family: Lucida, 'Lucida Grande', Tahoma, sans-serif; font-size: 13px; line-height: 19px; background-color: #ffffff;">pomelo框架包括三部分:</p><ul style="font-family: Lucida, 'Lucida Grande', Tahoma, sans-serif; font-size: 13px; line-height: 19px; background-color: #ffffff;"><li>框架, pomelo的核心, 与以往单进程的游戏框架不同, 它是高性能、分布式的游戏服务器框架，并且使用很简单。</li><li>库, 包括了开发游戏的常用工具库， 如人工智能(ai)、寻路、aoi等。</li><li>工具包, 包括管理控制台、 命令行工具、压力测试工具等。</li></ul><p style="font-family: Lucida, 'Lucida Grande', Tahoma, sans-serif; font-size: 13px; line-height: 19px; background-color: #ffffff;">pomelo的主要特性：</p><ul style="font-family: Lucida, 'Lucida Grande', Tahoma, sans-serif; font-size: 13px; line-height: 19px; background-color: #ffffff;"><li>快速、易上手的游戏开发模型和API。</li><li>高可伸缩的多进程架构， 支持MMO的场景分区和其它各类分区策略。</li><li>方便的服务器扩展机制，可快速扩展服务器类型和数量。</li><li>方便的请求、响应、广播、服务器通讯机制， 无需任何配置。</li><li>注重性能，在性能、可伸缩性上做了大量的测试、优化。</li><li>提供了较多扩展组件，包括游戏开发常用的库和工具包。</li><li>提供了完整的MMO demo代码(客户端html5)，可以作为很好的开发参考。</li><li>基于socket.io开发，支持socket.io支持的多种语言客户端。</li></ul><p style="font-family: Lucida, 'Lucida Grande', Tahoma, sans-serif; font-size: 13px; line-height: 19px; background-color: #ffffff;">网易pomelo开发团队在项目主页上列举了推荐pomelo的理由：</p><blockquote style="padding-right: 5px; padding-left: 5px; margin-right: 0px; margin-left: 20px; background-image: url(http://cdn3.infoq.com/styles/cn/i/bg-blockquote.gif); background-color: #fafafa; font-family: Lucida, 'Lucida Grande', Tahoma, sans-serif; font-size: 13px; line-height: 19px; background-position: 5px 5px; background-repeat: no-repeat no-repeat;"><p style="margin-top: 0px; margin-bottom: 0px;">高并发、高实时的游戏服务器的开发是很复杂的工作。跟Web应用一样，一个好的开源容器或开发框架可以大大减少游戏开发的复杂性，让开发变得更加容易。遗憾的是目前在游戏服务器开发领域一直没有太好的开源解决方案。 pomelo将填补这个空白， 打造一款完全开源的高性能（并发）游戏服务器框架。</p></blockquote><p style="font-family: Lucida, 'Lucida Grande', Tahoma, sans-serif; font-size: 13px; line-height: 19px; background-color: #ffffff;">pomelo的优势有以下几点：</p><ul style="font-family: Lucida, 'Lucida Grande', Tahoma, sans-serif; font-size: 13px; line-height: 19px; background-color: #ffffff;"><li>架构的可伸缩性好。 采用多进程单线程的运行架构，扩展服务器非常方便， Node.js的网络IO优势提供了高可伸缩性。</li><li>使用非常容易， 开发模型与Web应用的开发类似，基于convention over configuration的理念， 几乎零配置， API的设计也很精简， 很容易上手。</li><li>框架的松耦合和可扩展性好， 遵循Node.js微模块的原则， framework本身只有很少的代码，所有component、库、工具都可以用npm module的形式扩展进来。任何第三方都可以根据自己的需要开发自定义module。</li><li>提供完整的开源MMO游戏demo参考(基于HTML 5)。 一个超过1万行代码的游戏demo，使开发者可以随时借鉴demo的设计与开发思路。</li></ul><p style="font-family: Lucida, 'Lucida Grande', Tahoma, sans-serif; font-size: 13px; line-height: 19px; background-color: #ffffff;">pomelo为什么采用Node.js开发？</p><p style="font-family: Lucida, 'Lucida Grande', Tahoma, sans-serif; font-size: 13px; line-height: 19px; background-color: #ffffff;">Node.js自身特点与游戏服务器的特性惊人的吻合。 在Node.js的官方定义中， fast、scalable、realtime、network这几个特性都非常符合游戏服务器的要求。游戏服务器是个网络密集型的应用，对实时性要求极高，而Node.js在网络io上的优势也完全可以满足这点。使用Node.js开发游戏服务器的优势总结：</p><ul style="font-family: Lucida, 'Lucida Grande', Tahoma, sans-serif; font-size: 13px; line-height: 19px; background-color: #ffffff;"><li>io与可伸缩性的优势。io密集型的应用采用Node.js是最合适的， 可达到最好的可伸缩性。</li><li>多进程单线程的应用架构。Node.js天生采用单线程， 使它在处理复杂逻辑的时候无需考虑线程同步、锁、死锁等一系列问题， 减少了很多逻辑错误。 由多进程Node.js组成的服务器群是最理想的应用架构。</li><li>语言优势。使用javascript开发可以实现快速迭代，如果客户端使用HTML 5，更可实现代码共用。</li></ul><p style="font-family: Lucida, 'Lucida Grande', Tahoma, sans-serif; font-size: 13px; line-height: 19px; background-color: #ffffff;">网易pomelo开发团队介绍了游戏服务器的运行架构：</p><blockquote style="padding-right: 5px; padding-left: 5px; margin-right: 0px; margin-left: 20px; background-image: url(http://cdn3.infoq.com/styles/cn/i/bg-blockquote.gif); background-color: #fafafa; font-family: Lucida, 'Lucida Grande', Tahoma, sans-serif; font-size: 13px; line-height: 19px; background-position: 5px 5px; background-repeat: no-repeat no-repeat;"><p style="margin-top: 0px; margin-bottom: 0px;">一个真正高可扩展的游戏运行架构必须是多进程的。Google的<a href="http://code.google.com/p/gritsgame/" style="color: #0b59b2;">gritsgame</a>,、Mozilla的<a href="https://github.com/mozilla/BrowserQuest" style="color: #0b59b2;">browserquest</a>&nbsp;都采用了Node.js作为游戏服务器开发语言， 但它们都采用了单进程的Node.js服务器，缺乏扩展性，这使它们可以支撑的在线用户数量是很有限的（这两个游戏主要是作为HTML5游戏的 demo）。而多进程的架构可以很好的实现游戏服务器的的扩展性，达到支撑较多在线用户、降低服务器压力等要求。</p></blockquote><p style="font-family: Lucida, 'Lucida Grande', Tahoma, sans-serif; font-size: 13px; line-height: 19px; background-color: #ffffff;">该游戏运行架构表面上看与web应用运行架构很类似，connector类似于web应用的apache/nginx等web服务器，后端的服务器群类似于web应用中的应用服务器（如tomcat），但实际上存在着很大的差别：</p><ul style="font-family: Lucida, 'Lucida Grande', Tahoma, sans-serif; font-size: 13px; line-height: 19px; background-color: #ffffff;"><li>长连接与短连接。web应用使用基于http的短连接以达到最大的可扩展性，游戏应用采用基于socket(websocket)的长连接，以达到最大的实时性。</li><li>分区策略不同。web应用的分区可以根据负载均衡自由决定， 而游戏则是基于场景(area)的分区模式， 这使同场景的玩家跑在一个进程内，以达到最少的跨进程调用。</li><li>有状态和无状态。web应用是无状态的， 可以达到无限的扩展。 而游戏应用则是有状态的， 由于基于场景的分区策略，它的请求必须路由到指定的服务器， 这也使游戏达不到web应用同样的可扩展性。</li><li>广播模式和request/response模式。web应用采用了基于request/response的请求响应模式。而游戏应用则更频繁地使用广播，由于玩家在游戏里的行动要实时地通知场景中的其它玩家， 必须通过广播的模式实时发送。这也使游戏在网络通信上的要求高于web应用。</li></ul><p style="font-family: Lucida, 'Lucida Grande', Tahoma, sans-serif; font-size: 13px; line-height: 19px; background-color: #ffffff;">pomelo framework的组成架构如图所示：<img _p="true" _href="img://q.png" src="http://www.infoq.com/resource/news/2012/11/pomelo-opensource/zh/resources/q.png" alt="" style="border: 0px;" /></p><p align="center" style="font-family: Lucida, 'Lucida Grande', Tahoma, sans-serif; font-size: 13px; line-height: 19px; background-color: #ffffff;">图片来源： Github网易pomelo项目介绍</p><ul style="font-family: Lucida, 'Lucida Grande', Tahoma, sans-serif; font-size: 13px; line-height: 19px; background-color: #ffffff;"><li>server management, pomelo是个真正多进程、分布式的游戏服务器。因此各游戏server(进程)的管理是pomelo很重要的部分，框架通过抽象使服务器的管理非常容易。</li><li>network, 请求、响应、广播、RPC、session管理等构成了整个游戏框架的脉络，所有游戏流程都构建在这个脉络上。</li><li>application, 应用的定义、component管理，上下文配置， 这些使pomelo framework的对外接口很简单，并且具有松耦合、可插拔架构。</li></ul><p style="font-family: Lucida, 'Lucida Grande', Tahoma, sans-serif; font-size: 13px; line-height: 19px; background-color: #ffffff;">pomelo的架构设计目标：</p><ul style="font-family: Lucida, 'Lucida Grande', Tahoma, sans-serif; font-size: 13px; line-height: 19px; background-color: #ffffff;"><li>服务器（进程）的抽象与扩展：在web应用中， 每个服务器是无状态、对等的， 开发者无需通过框架或容器来管理服务器。但游戏应用不同， 游戏可能需要包含多种不同类型的服务器，每类服务器在数量上也可能有不同的需求。这就需要框架对服务器进行抽象和解耦，支持服务器类型和数量上的扩展。</li><li>客户端的请求、响应、广播：客户端的请求、响应与web应用是类似的， 但框架是基于长连接的， 实现模式与http请求有一定差别。广播是游戏服务器最频繁的操作， 需要方便的API， 并且在性能上达到极致。</li><li>服务器间的通讯、调用：尽管框架尽量避免跨进程调用，但进程间的通讯是不可避免的， 因此需要一个方便好用的RPC框架来支撑。</li><li>松耦合、可插拔的应用架构：应用的扩展性很重要， pomelo framework支持以component的形式插入任何第三方组件, 也支持加入自定义的路由规则、 自定义的filter等。</li></ul><img src ="http://www.cppblog.com/HappySky2046/aggbug/195992.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/HappySky2046/" target="_blank">探路者</a> 2012-12-04 23:36 <a href="http://www.cppblog.com/HappySky2046/articles/195992.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>构建高可用、可扩展的应用</title><link>http://www.cppblog.com/HappySky2046/articles/195991.html</link><dc:creator>探路者</dc:creator><author>探路者</author><pubDate>Tue, 04 Dec 2012 15:35:00 GMT</pubDate><guid>http://www.cppblog.com/HappySky2046/articles/195991.html</guid><wfw:comment>http://www.cppblog.com/HappySky2046/comments/195991.html</wfw:comment><comments>http://www.cppblog.com/HappySky2046/articles/195991.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/HappySky2046/comments/commentRss/195991.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/HappySky2046/services/trackbacks/195991.html</trackback:ping><description><![CDATA[<p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px; font-family: 'Lucida Grande', 'Lucida Sans Unicode', Arial, Verdana, sans-serif; line-height: 22.383333206176758px;">前不久，Facebook宣布投资10亿美元收购仅成立15个月的移动照片分享应用Instagram，消息传出时，人们不仅惊叹于这笔巨额的交易，更为这支13个人的小团队感到不可思议。Instagram的Android版客户端发布时，24小时内下载量超过100万，高峰期达到每分钟2000次，是下载量最大的Android应用之一。究竟是什么原因让这支团队在很短的时间内一鸣惊人？又是什么技术让他们在巨大的下载量下顶住了压力？让我们回顾一下Instagram开发团队奉行的3大原则：</p><ul style="margin: 5px 0px 15px; padding: 0px 0px 0px 20px; border: 0px; outline: 0px; font-family: 'Lucida Grande', 'Lucida Sans Unicode', Arial, Verdana, sans-serif; line-height: 22.383333206176758px;"><li style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">Keep it very simple（极简主义）；</li><li style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">Don&#8217;t re-invent the wheel （不重复发明轮子）；</li><li style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">with proven and solid technologies when you can （能用就用靠谱的技术）；</li></ul><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px; font-family: 'Lucida Grande', 'Lucida Sans Unicode', Arial, Verdana, sans-serif; line-height: 22.383333206176758px;">总而言之，专注于自己的业务和擅长领域，其他事情让更专业的人去做。Instagram选择了美国的亚马逊云计算平台作为基础设施提供商，它部署了数以百计的云服务器和存储服务，却只有区区3名工程师负责维护，不需要任何现场人员支持。如果依赖于传统的IDC服务，光是把这几百台服务器托管到IDC机房，就需要数天时间和大量的人力成本。每当发布一个新版本时，Instagram所要做的只是在云计算平台上开启更多的服务器，便可稳坐钓鱼台，看着自己应用的下载量节节攀升了。</p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px; font-family: 'Lucida Grande', 'Lucida Sans Unicode', Arial, Verdana, sans-serif; line-height: 22.383333206176758px;">阿里云弹性计算平台（Elastic Compute Service，简称ECS）面向中国互联网开发者和站长，致力于为中国的Instagram提供靠谱的互联网基础服务。它基于底层的飞天分布式计算系统，结合高性能虚拟化技术，实现了计算、存储和网络资源的统一调度和弹性分配。在具体的产品形式上，客户接触的是最简单的云服务器，与物理机无二，没有任何的使用门槛。由于采用了云计算技术，相比传统的IDC托管服务，弹性计算在自助管理、资源组合灵活性、基础环境定制化、数据安全性及硬件资源利用率上都有不小的优势。</p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px; font-family: 'Lucida Grande', 'Lucida Sans Unicode', Arial, Verdana, sans-serif; line-height: 22.383333206176758px;">在本文中，我们将和大家分享在云计算平台上构建高可用、可扩展应用的一些进阶技巧。考虑到有些读者尚未接触过ECS，所以在进入正题之前，让我们简单浏览一下ECS的各项特性。</p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px; font-family: 'Lucida Grande', 'Lucida Sans Unicode', Arial, Verdana, sans-serif; line-height: 22.383333206176758px;"><strong style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">自助管理</strong></p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px; font-family: 'Lucida Grande', 'Lucida Sans Unicode', Arial, Verdana, sans-serif; line-height: 22.383333206176758px;">ECS在aliyun.com的控制台中提供了多种用户自助的操作，例如最为常见的创建、启动、关闭云服务器，将来还会陆续推出比较高级的快照、回滚、自定义镜像（Image）等功能。回想我们以前遇到服务器不可访问时，提交工单、电话催促，在经历漫长等待之后，也未必能够得到一个满意的答复。现在，我们可以在控制台中全程监控和管理每一台服务器的运行情况，从而做出快速的决定&#8212;&#8212;重启或者部署新的服务器。</p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px; font-family: 'Lucida Grande', 'Lucida Sans Unicode', Arial, Verdana, sans-serif; line-height: 22.383333206176758px;">ECS支持目前主流的Windows和Linux系列操作系统。用户不仅可以使用这些标准的镜像，还可以在此基础上修改配置、安装软件，创建出自己的镜像，当要快速恢复基础环境或者批量部署集群时，自定义镜像将成为提高运维效率的利器。</p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px; font-family: 'Lucida Grande', 'Lucida Sans Unicode', Arial, Verdana, sans-serif; line-height: 22.383333206176758px;">图1简单地描述了一个自定义镜像的生产过程。</p><div id="attachment_12836"  aligncenter"="" style="margin: 10px auto 1em; padding: 4px; border: 0px; outline: 0px; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; text-align: center; font-family: 'Lucida Grande', 'Lucida Sans Unicode', Arial, Verdana, sans-serif; line-height: 22.383333206176758px; width: 398px;"><img wp-image-12836=""  "="" title="图1  自定义镜像" src="http://www.programmer.com.cn/wp-content/uploads/2012/07/%E8%87%AA%E5%AE%9A%E4%B9%89%E9%95%9C%E5%83%8F.jpg" alt="" width="388" height="194" style="margin: 5px 0px 0px; padding: 0px; border: 0px none; outline: 0px;" /><p style="margin: 0px; padding: 6px 3px 2px; border: 0px; outline: 0px; font-size: 10px; line-height: 16px; text-indent: 28px;">图1 自定义镜像</p></div><ul style="margin: 5px 0px 15px; padding: 0px 0px 0px 20px; border: 0px; outline: 0px; font-family: 'Lucida Grande', 'Lucida Sans Unicode', Arial, Verdana, sans-serif; line-height: 22.383333206176758px;"><li style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">使用标准镜像创建一台云服务器；</li><li style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">用户登录云服务器，安装自己所需的软件，配置好系统参数；</li><li style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">安全关机，然后将云服务器当前状态存为一个自定义镜像；</li><li style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">随后，用户就可以使用刚创建的自定义镜像启动更多的云服务器了。</li></ul><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px; font-family: 'Lucida Grande', 'Lucida Sans Unicode', Arial, Verdana, sans-serif; line-height: 22.383333206176758px;"><span style="margin: 0px; padding: 0px; border: 0px; outline: 0px; color: #3366ff;"><strong style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">数据可靠性</strong></span></p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px; font-family: 'Lucida Grande', 'Lucida Sans Unicode', Arial, Verdana, sans-serif; line-height: 22.383333206176758px;">对于写入VM磁盘的数据，ECS会实时地在不同的交换机下同步3份拷贝，当集群中的磁盘损坏时，后台进程也会自动地重建故障磁盘的数据。相比常见的RAID硬件方案，这种分布式存储系统能够提供更高的数据安全保障，因为它不受单台服务器可用性的限制，并且，由于多台服务器可以并发处理，数据恢复的时间更短。</p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px; font-family: 'Lucida Grande', 'Lucida Sans Unicode', Arial, Verdana, sans-serif; line-height: 22.383333206176758px;">ECS提供的在线快照功能可以完美地替代传统的复制备份，它采用先进的增量数据算法，确保做到备份空间和时间的最优化。当用户数据被误删或者系统被病毒破坏时，只需要一个简单操作就可以瞬间恢复环境。</p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px; font-family: 'Lucida Grande', 'Lucida Sans Unicode', Arial, Verdana, sans-serif; line-height: 22.383333206176758px;"><span style="margin: 0px; padding: 0px; border: 0px; outline: 0px; color: #3366ff;"><strong style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">自动故障恢复</strong></span></p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px; font-family: 'Lucida Grande', 'Lucida Sans Unicode', Arial, Verdana, sans-serif; line-height: 22.383333206176758px;">有了分布式存储的支持，ECS可以提供比传统主机或VPS服务更高的可用性指标。当一台物理机损坏时，ECS会自动监测到硬件故障，在第一时间内把云服务器迁移到新的宿主机上，同时硬盘数据保持最后一刻的状态。如图2所示。</p><div id="attachment_12837"  aligncenter"="" style="margin: 10px auto 1em; padding: 4px; border: 0px; outline: 0px; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; text-align: center; font-family: 'Lucida Grande', 'Lucida Sans Unicode', Arial, Verdana, sans-serif; line-height: 22.383333206176758px; width: 537px;"><img wp-image-12837=""  "="" title="图2  自动故障恢复" src="http://www.programmer.com.cn/wp-content/uploads/2012/07/%E8%87%AA%E5%8A%A8%E6%95%85%E9%9A%9C%E6%81%A2%E5%A4%8D.jpg" alt="" width="527" height="296" style="margin: 5px 0px 0px; padding: 0px; border: 0px none; outline: 0px;" /><p style="margin: 0px; padding: 6px 3px 2px; border: 0px; outline: 0px; font-size: 10px; line-height: 16px; text-indent: 28px;">图2 自动故障恢复</p></div><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px; font-family: 'Lucida Grande', 'Lucida Sans Unicode', Arial, Verdana, sans-serif; line-height: 22.383333206176758px;">从以上介绍可以看出，托管在弹性计算平台上的应用可以获得更多的保障，但我们是否可以认为，将应用搬到云计算平台之后，它就能跑得欢快、永不宕机，还能自动扩展了？答案是NO！</p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px; font-family: 'Lucida Grande', 'Lucida Sans Unicode', Arial, Verdana, sans-serif; line-height: 22.383333206176758px;">每时每刻，硬盘、主板、电源或者网络设备都可能突然损坏，甚至整个数据中心发生停电。云计算技术没有办法解决所有硬件问题，只是降低了某些故障的发生几率，例如：</p><ul style="margin: 5px 0px 15px; padding: 0px 0px 0px 20px; border: 0px; outline: 0px; font-family: 'Lucida Grande', 'Lucida Sans Unicode', Arial, Verdana, sans-serif; line-height: 22.383333206176758px;"><li style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">普通SATA的年损坏率在2%~4%，但使用分布式存储的年损坏率在1&#8240;以下；</li><li style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">自动故障恢复只是减少了服务器的宕机时间，但不能防止宕机。</li></ul><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px; font-family: 'Lucida Grande', 'Lucida Sans Unicode', Arial, Verdana, sans-serif; line-height: 22.383333206176758px;">如果我们的应用只能跑在单台服务器上，只能依赖单台设备的硬件升级才能应付日益增长的访问量，那么这种应用的宕机是迟早的事情。事实上，我们需要从部署架构和应用架构两个方面来破解这个难题。</p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px; font-family: 'Lucida Grande', 'Lucida Sans Unicode', Arial, Verdana, sans-serif; line-height: 22.383333206176758px;"><span style="margin: 0px; padding: 0px; border: 0px; outline: 0px; color: #3366ff;"><strong style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">部署架构</strong></span></p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px; font-family: 'Lucida Grande', 'Lucida Sans Unicode', Arial, Verdana, sans-serif; line-height: 22.383333206176758px;">既然没有什么硬件是永不损坏的，我们是否可以用多份冗余的硬件来降低故障的概率？如果挨在一起的服务器被一把火烧掉的可能性太大，我们是否可以把它们分散在不同的集群？如果数据可能被破坏，是否要经常做些备份？&#8230;&#8230;</p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px; font-family: 'Lucida Grande', 'Lucida Sans Unicode', Arial, Verdana, sans-serif; line-height: 22.383333206176758px;">把各种故障因素都考虑一遍，我们就可以得出下面这个大致的部署框架。</p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px; font-family: 'Lucida Grande', 'Lucida Sans Unicode', Arial, Verdana, sans-serif; line-height: 22.383333206176758px;"><strong style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">以集群方式提供服务</strong></p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px; font-family: 'Lucida Grande', 'Lucida Sans Unicode', Arial, Verdana, sans-serif; line-height: 22.383333206176758px;">Web服务器、缓存服务器都是非常适合部署为集群的，单台服务器损坏不会影响整个网站的访问。数据库服务器稍难一些，但它们也提供了主从复制、读写分离的解决方案。</p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px; font-family: 'Lucida Grande', 'Lucida Sans Unicode', Arial, Verdana, sans-serif; line-height: 22.383333206176758px;"><strong style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">将云服务器分布在不同的可用区（Zone）下</strong></p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px; font-family: 'Lucida Grande', 'Lucida Sans Unicode', Arial, Verdana, sans-serif; line-height: 22.383333206176758px;">不同的可用区代表数据中心里的不同物理位置，同一可用区内的服务器可能同时遭遇网络设备、电力等故障，因此，把一个集群内的云服务器分散到不同的可用区甚至不同的数据中心（Region）是个明智的选择。</p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px; font-family: 'Lucida Grande', 'Lucida Sans Unicode', Arial, Verdana, sans-serif; line-height: 22.383333206176758px;"><strong style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">为Web服务集群配置负载均衡与DNS轮询</strong></p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px; font-family: 'Lucida Grande', 'Lucida Sans Unicode', Arial, Verdana, sans-serif; line-height: 22.383333206176758px;">多台Web服务器可以通过配置负载均衡或者DNS轮询提供对外服务。DNS轮询，负载均衡方式会更加灵活，因为它对外屏蔽了服务器的真实IP，当负载均衡资源池内增加或减少服务器时，对客户是透明的。而DNS存在时延的问题，集群发生调整后，很有可能造成部分用户在很长一段时间内无法正常访问网站。</p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px; font-family: 'Lucida Grande', 'Lucida Sans Unicode', Arial, Verdana, sans-serif; line-height: 22.383333206176758px;">另外，负载均衡能够跟踪后端应用服务器的健康状态，自动排除有故障的节点，避免出现服务时断时续的问题。<br />对于特别大的应用，我们推荐使用负载均衡+DNS轮询的方式，只是这里的DNS轮询域名指向的是负载均衡的VIP。</p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px; font-family: 'Lucida Grande', 'Lucida Sans Unicode', Arial, Verdana, sans-serif; line-height: 22.383333206176758px;"><strong style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">实现动态部署</strong></p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px; font-family: 'Lucida Grande', 'Lucida Sans Unicode', Arial, Verdana, sans-serif; line-height: 22.383333206176758px;">为了应对经常性的业务推广和可能的DDoS网络攻击，实现系统与应用程序的一键部署很重要。系统管理员可以根据应用的当前状态（CPU、内存使用率、HTTP的响应时间等）作出判断，即时增加服务器，并且快速部署应用程序，顶住突增的业务流量。如果实现得更智能一些，可以在应用服务器内部部署一些监控程序，由主控程序判断当前整个集群的负载情况，调用ECS API自动增减服务节点。</p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px; font-family: 'Lucida Grande', 'Lucida Sans Unicode', Arial, Verdana, sans-serif; line-height: 22.383333206176758px;">用一台主控机去批量操作其他云服务器时，应该尽量使用一些便捷工具，例如SSH密钥对，它实现了授权服务器间的免登录，使得集群管理更加简单。</p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px; font-family: 'Lucida Grande', 'Lucida Sans Unicode', Arial, Verdana, sans-serif; line-height: 22.383333206176758px;"><strong style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">定时备份很重要</strong></p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px; font-family: 'Lucida Grande', 'Lucida Sans Unicode', Arial, Verdana, sans-serif; line-height: 22.383333206176758px;">前面说到，没有什么技术可以保证100%的数据安全，你的数据始终面临误删文件、病毒破坏、程序写错、硬件损坏等种种可能的风险。如果你的数据非常重要，请定期备份！在弹性计算平台上，这件事情相对简单，快照功能自动完成增量数据备份。然而，单个物理位置的存储始终会面临地震、火灾等灾难的威胁，如果你觉得还不够安全，或者有异地使用的需要，且能够承受异地备份带来的存储、带宽等成本，可以自行拷贝数据文件。弹性计算平台也正在考虑跨机房的容灾方案。</p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px; font-family: 'Lucida Grande', 'Lucida Sans Unicode', Arial, Verdana, sans-serif; line-height: 22.383333206176758px;"><strong style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">将应用程序配置为自恢复的</strong></p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px; font-family: 'Lucida Grande', 'Lucida Sans Unicode', Arial, Verdana, sans-serif; line-height: 22.383333206176758px;">单台服务器的硬件故障是常见现象，以现有的云计算技术能力，尚无法做到不影响云服务器的运行，但ECS可以快速检测到故障特征，并且将云服务器自动迁移到新的宿主机上。这里存在一个问题，虽然云服务器重新启动了，而且硬盘数据恢复到最后一刻的状态，但原先正在运行的应用程序中止了。为了让你的服务中断时间尽量地缩短，避免人工的介入，强烈建议将应用程序及相关服务设置为开机自启动，这样，你就可以高枕无忧地睡大觉，不用半夜起来恢复应用，尽管只是几个点击或者命令操作。</p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px; font-family: 'Lucida Grande', 'Lucida Sans Unicode', Arial, Verdana, sans-serif; line-height: 22.383333206176758px;"><strong style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">加固系统</strong></p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px; font-family: 'Lucida Grande', 'Lucida Sans Unicode', Arial, Verdana, sans-serif; line-height: 22.383333206176758px;">安全也是高可用的重要前提之一。放在IDC机房中的服务器时时面临各种恶意攻击，图3是我们偶然截取的一个攻击片段。</p><div id="attachment_12853"  aligncenter"="" style="margin: 10px auto 1em; padding: 4px; border: 0px; outline: 0px; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; text-align: center; font-family: 'Lucida Grande', 'Lucida Sans Unicode', Arial, Verdana, sans-serif; line-height: 22.383333206176758px; width: 443px;"><img wp-image-12853=""  "="" title="图3 端口扫描攻击" src="http://www.programmer.com.cn/wp-content/uploads/2012/07/004.jpg" alt="" width="433" height="148" style="margin: 5px 0px 0px; padding: 0px; border: 0px none; outline: 0px;" /><p style="margin: 0px; padding: 6px 3px 2px; border: 0px; outline: 0px; font-size: 10px; line-height: 16px; text-indent: 28px;">图3 端口扫描攻击</p></div><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px; font-family: 'Lucida Grande', 'Lucida Sans Unicode', Arial, Verdana, sans-serif; line-height: 22.383333206176758px;">这台服务器在循环探测机房中每一台机器的1433端口，有经验的读者很快猜出来了，它是在试探SQLServer服务，一旦SQLServer被攻破，再利用SQLServer管理员的系统权限漏洞，马上就有一些机器沦为肉鸡。</p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px; font-family: 'Lucida Grande', 'Lucida Sans Unicode', Arial, Verdana, sans-serif; line-height: 22.383333206176758px;">阿里云弹性计算服务在平台层面就屏蔽了一些影响范围很大的恶意攻击，例如篡改MAC、伪造IP、发送ARP欺骗包等，但用户的系统还是要遵循一些安全最佳实践，才能让自己的系统更加稳固。</p><ul style="margin: 5px 0px 15px; padding: 0px 0px 0px 20px; border: 0px; outline: 0px; font-family: 'Lucida Grande', 'Lucida Sans Unicode', Arial, Verdana, sans-serif; line-height: 22.383333206176758px;"><li style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">关闭不必要的系统服务</li></ul><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px; font-family: 'Lucida Grande', 'Lucida Sans Unicode', Arial, Verdana, sans-serif; line-height: 22.383333206176758px;">越多的服务意味着越多的漏洞，特别是Windows共享文件夹、远程修改注册表项等服务都存在巨大的风险，如果你的工作不需要这些服务，请马上关闭。</p><ul style="margin: 5px 0px 15px; padding: 0px 0px 0px 20px; border: 0px; outline: 0px; font-family: 'Lucida Grande', 'Lucida Sans Unicode', Arial, Verdana, sans-serif; line-height: 22.383333206176758px;"><li style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">及时升级系统补丁</li></ul><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px; font-family: 'Lucida Grande', 'Lucida Sans Unicode', Arial, Verdana, sans-serif; line-height: 22.383333206176758px;">前段时间爆出的微软高危RDP漏洞让很多用户深受其害，通过一个简单的Python脚本，黑客就可以直接获取系统管理员权限或者直接把服务器打至蓝屏。不要忽略操作系统厂商的安全警告，一旦遭遇攻击，将造成不可挽回的损失。</p><ul style="margin: 5px 0px 15px; padding: 0px 0px 0px 20px; border: 0px; outline: 0px; font-family: 'Lucida Grande', 'Lucida Sans Unicode', Arial, Verdana, sans-serif; line-height: 22.383333206176758px;"><li style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">开启系统防火墙</li></ul><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px; font-family: 'Lucida Grande', 'Lucida Sans Unicode', Arial, Verdana, sans-serif; line-height: 22.383333206176758px;">采用白名单控制策略，只开放最小集合的端口。对于数据库服务器，更要设置IP白名单，仅允许前端的Web服务器访问；对于Web服务器，只对外开放80端口。</p><ul style="margin: 5px 0px 15px; padding: 0px 0px 0px 20px; border: 0px; outline: 0px; font-family: 'Lucida Grande', 'Lucida Sans Unicode', Arial, Verdana, sans-serif; line-height: 22.383333206176758px;"><li style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">修改常见服务的端口</li></ul><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px; font-family: 'Lucida Grande', 'Lucida Sans Unicode', Arial, Verdana, sans-serif; line-height: 22.383333206176758px;">从刚才的攻击示例看出，黑客虽然漫无目的地扫描同一网段的IP，但攻击的目标端口只有一个1433，这是SQLServer的默认配置。为了减少这类攻击，最有效的方式就是修改数据库、FTP这类常见服务的默认端口，增加黑客扫描的难度。</p><ul style="margin: 5px 0px 15px; padding: 0px 0px 0px 20px; border: 0px; outline: 0px; font-family: 'Lucida Grande', 'Lucida Sans Unicode', Arial, Verdana, sans-serif; line-height: 22.383333206176758px;"><li style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">加密数据传输</li></ul><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px; font-family: 'Lucida Grande', 'Lucida Sans Unicode', Arial, Verdana, sans-serif; line-height: 22.383333206176758px;">我曾经遇到过一个很奇怪的现象，在一台Windows 2003服务器上，应用的负载很低，但CPU利用率达到了99%，从任务管理器中看到，有无数个winlogon.exe进程疯狂消耗CPU，当时百思不得其解。一天之后，这台服务器就沦陷了，我才恍然大悟，一定是攻击者在尝试破解密码。对于这类攻击，即使调整密码长度增加破解难度也收效不大，因为攻击过程会消耗大量的系统资源，正常的业务根本无法进行。何况，现在的服务器计算能力越来越强，一个密码的安全性实在太低了。</p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px; font-family: 'Lucida Grande', 'Lucida Sans Unicode', Arial, Verdana, sans-serif; line-height: 22.383333206176758px;">一些加密传输方式能够有效地抵御这类攻击，也能减少传输过程中的敏感信息泄露问题。Windows可以配置远程桌面服务使用SSL传输，要求客户端必须持有证书登录。Linux则可以使用SSH登录密钥对。结合修改默认端口的方式，将使你的系统安全性提高一个层次。</p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px; font-family: 'Lucida Grande', 'Lucida Sans Unicode', Arial, Verdana, sans-serif; line-height: 22.383333206176758px;">友情提醒：如果你开启了防火墙，又修改了默认的远程桌面或者SSH端口，请务必在防火墙中设置这些服务的白名单，否则就悲剧了。</p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px; font-family: 'Lucida Grande', 'Lucida Sans Unicode', Arial, Verdana, sans-serif; line-height: 22.383333206176758px;"><span style="margin: 0px; padding: 0px; border: 0px; outline: 0px; color: #3366ff;"><strong style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">应用架构</strong></span></p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px; font-family: 'Lucida Grande', 'Lucida Sans Unicode', Arial, Verdana, sans-serif; line-height: 22.383333206176758px;">要支持上述高可用、可扩展的部署架构，应用程序也要做相应的调整。</p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px; font-family: 'Lucida Grande', 'Lucida Sans Unicode', Arial, Verdana, sans-serif; line-height: 22.383333206176758px;"><strong style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">Web应用的无状态设计</strong></p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px; font-family: 'Lucida Grande', 'Lucida Sans Unicode', Arial, Verdana, sans-serif; line-height: 22.383333206176758px;">Web应用的诸多因素可能造成系统无法扩展：本地存放的上传文件、进程内的Session等。以上传文件为例，假设使用了本地存储，用户第一个请求上传了一个头像文件，存放在Web-A服务器上，接着刷新页面，但这个请求被发送到Web-B服务器上，他惊奇地发现：上传的头像文件不见了！要解决这个问题，必须把上传文件存放到共享的文件夹，Web服务器不能保留任何自己的数据（即无状态）。而对于Session数据，一般的建议是用Cookie代替，或者存放到共享的Session服务器或者数据库中。</p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px; font-family: 'Lucida Grande', 'Lucida Sans Unicode', Arial, Verdana, sans-serif; line-height: 22.383333206176758px;"><strong style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">用分布式服务代替单点的服务</strong></p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px; font-family: 'Lucida Grande', 'Lucida Sans Unicode', Arial, Verdana, sans-serif; line-height: 22.383333206176758px;">单点就意味着故障，不仅有可用性的风险也有性能瓶颈的问题。常见的单点一般出现在共享文件服务器、Session服务器、缓存服务器、数据库服务器。阿里云计算平台提供了一系列分布式服务，是这些单点服务的可行替代方案。</p><ul style="margin: 5px 0px 15px; padding: 0px 0px 0px 20px; border: 0px; outline: 0px; font-family: 'Lucida Grande', 'Lucida Sans Unicode', Arial, Verdana, sans-serif; line-height: 22.383333206176758px;"><li style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">需要无空间和访问频率限制的小文件存储？用开放存储服务（OSS）。</li><li style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">需要可弹性分配存储空间和IO能力的数据库？用关系型数据库服务（RDS）。</li><li style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">需要海量结构化数据存储服务？用开放结构化数据服务（OTS）。</li></ul><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px; font-family: 'Lucida Grande', 'Lucida Sans Unicode', Arial, Verdana, sans-serif; line-height: 22.383333206176758px;">对于平台暂时不提供的分布式缓存服务，业界也提供了一些解决方案，例如Memcached集群技术，但这也对应用程序的设计提出了更高的要求，开发者必须清楚各种服务的HA原理，还需要了解一致性哈希算法等细节的实现。</p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px; font-family: 'Lucida Grande', 'Lucida Sans Unicode', Arial, Verdana, sans-serif; line-height: 22.383333206176758px;"><strong style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">应用的安全不容忽视</strong></p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px; font-family: 'Lucida Grande', 'Lucida Sans Unicode', Arial, Verdana, sans-serif; line-height: 22.383333206176758px;">安全不仅是操作系统配置的问题，堡垒更容易从内部被攻破，而这个内鬼很有可能就是我们的应用。从概率上说，一个复杂程序会比一个简单程序多很多漏洞，而Web应用涉及数据库、应用服务器、缓存等诸多组件，稍有不慎，攻击的后门就会向黑客敞开。常见的Web服务漏洞有以下几种。</p><ul style="margin: 5px 0px 15px; padding: 0px 0px 0px 20px; border: 0px; outline: 0px; font-family: 'Lucida Grande', 'Lucida Sans Unicode', Arial, Verdana, sans-serif; line-height: 22.383333206176758px;"><li style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">XSS跨站脚本攻击</li></ul><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px; font-family: 'Lucida Grande', 'Lucida Sans Unicode', Arial, Verdana, sans-serif; line-height: 22.383333206176758px;">这类Web攻击最为普遍，一般发生在允许用户输入内容的页面，尤其是提供富文本编辑的模块。几乎所有的网站都会被XSS攻击光顾，但防御这类攻击也是最为简单的：限制用户输入，并且在页面输出内容时对敏感字符进行编码，相对来说，后者更为重要一些。PHP语言的htmlspecialchars函数、Java Jakarta commons的StringEscapeUtils类都是实现编码功能的快捷工具。</p><ul style="margin: 5px 0px 15px; padding: 0px 0px 0px 20px; border: 0px; outline: 0px; font-family: 'Lucida Grande', 'Lucida Sans Unicode', Arial, Verdana, sans-serif; line-height: 22.383333206176758px;"><li style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">SQL注入攻击</li></ul><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px; font-family: 'Lucida Grande', 'Lucida Sans Unicode', Arial, Verdana, sans-serif; line-height: 22.383333206176758px;">只要应用代码中存在这样的SQL：</p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px; font-family: 'Lucida Grande', 'Lucida Sans Unicode', Arial, Verdana, sans-serif; line-height: 22.383333206176758px;"><img wp-image-12839"="" title="SQL" src="http://www.programmer.com.cn/wp-content/uploads/2012/07/0011.jpg" alt="" width="421" height="32" style="margin: 0px auto; padding: 0px; border: none; outline: 0px; display: block;" /></p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px; font-family: 'Lucida Grande', 'Lucida Sans Unicode', Arial, Verdana, sans-serif; line-height: 22.383333206176758px;">那么这个应用距离沦陷也就不远了，攻击者只要输入一个值为的</p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px; font-family: 'Lucida Grande', 'Lucida Sans Unicode', Arial, Verdana, sans-serif; line-height: 22.383333206176758px;"><img wp-image-12841"="" title="name" src="http://www.programmer.com.cn/wp-content/uploads/2012/07/0022.jpg" alt="" width="202" height="21" style="margin: 0px auto; padding: 0px; border: none; outline: 0px; display: block;" /></p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px; font-family: 'Lucida Grande', 'Lucida Sans Unicode', Arial, Verdana, sans-serif; line-height: 22.383333206176758px;">name就可以轻易进入你的应用系统。杜绝这类问题的方法有2种：对输入的特殊字符进行转义，例如PHP的mysql_real_escape_string函数；或者采用参数化的SQL，例如：</p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px; font-family: 'Lucida Grande', 'Lucida Sans Unicode', Arial, Verdana, sans-serif; line-height: 22.383333206176758px;"><img wp-image-12843"="" title="参数化的SQL" src="http://www.programmer.com.cn/wp-content/uploads/2012/07/003.jpg" alt="" width="419" height="33" style="margin: 0px auto; padding: 0px; border: none; outline: 0px; display: block;" /><br />后者实现更加优雅，绝对避免了SQL注入的风险，而且在提升数据库的查询性能上也会有所帮助。</p><ul style="margin: 5px 0px 15px; padding: 0px 0px 0px 20px; border: 0px; outline: 0px; font-family: 'Lucida Grande', 'Lucida Sans Unicode', Arial, Verdana, sans-serif; line-height: 22.383333206176758px;"><li style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">上传文件漏洞</li></ul><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px; font-family: 'Lucida Grande', 'Lucida Sans Unicode', Arial, Verdana, sans-serif; line-height: 22.383333206176758px;">这是最为危险的应用级漏洞，特别容易出现在允许用户上传内容的网站中。假设一个tomcat搭建的Web网站允许用户上传附件，却忘了限制上传目录的可执行权限，攻击者就可以上传一个带webshell的jsp文件，通过访问这个上传文件的URL就可以完全控制网站服务器。一定要取消上传文件的可执行权限，另外，绝不允许这类文件被当作服务端脚本解析。赶紧为你的网站实施安全策略吧！</p><ul style="margin: 5px 0px 15px; padding: 0px 0px 0px 20px; border: 0px; outline: 0px; font-family: 'Lucida Grande', 'Lucida Sans Unicode', Arial, Verdana, sans-serif; line-height: 22.383333206176758px;"><li style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">Cookie与传输加密</li></ul><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px; font-family: 'Lucida Grande', 'Lucida Sans Unicode', Arial, Verdana, sans-serif; line-height: 22.383333206176758px;">只要会用HttpWatch、Firebug等开发工具，大家都可以看到各大网站的Cookie数据，而这些Cookie正是网站用于鉴别用户身份的凭证。通过分析Cookie构成，黑客有可能猜测出网站的鉴权策略。要想让你的应用更安全，可以对Cookie等敏感数据进行加密。如果你的网站还包含在线支付功能，部署带授权证书的HTTPS是必不可少的，这也是很多第三方支付平台的强制要求。</p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px; font-family: 'Lucida Grande', 'Lucida Sans Unicode', Arial, Verdana, sans-serif; line-height: 22.383333206176758px;">综上所述，虽然云计算平台提供了更灵活、更稳定的基础服务保障，但它不足以解决应用的高可用性和可扩展性问题，应用自身必须在架构设计和部署上充分考虑各种意外情况，才能实现真正意义上的高可用、可扩展。</p><img src ="http://www.cppblog.com/HappySky2046/aggbug/195991.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/HappySky2046/" target="_blank">探路者</a> 2012-12-04 23:35 <a href="http://www.cppblog.com/HappySky2046/articles/195991.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>软件架构师12项修炼</title><link>http://www.cppblog.com/HappySky2046/articles/195990.html</link><dc:creator>探路者</dc:creator><author>探路者</author><pubDate>Tue, 04 Dec 2012 15:30:00 GMT</pubDate><guid>http://www.cppblog.com/HappySky2046/articles/195990.html</guid><wfw:comment>http://www.cppblog.com/HappySky2046/comments/195990.html</wfw:comment><comments>http://www.cppblog.com/HappySky2046/articles/195990.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/HappySky2046/comments/commentRss/195990.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/HappySky2046/services/trackbacks/195990.html</trackback:ping><description><![CDATA[<div style="margin: 0px; border: 0px; outline: 0px; font-family: 'Lucida Grande', 'Lucida Sans Unicode', Arial, Verdana, sans-serif; line-height: 22.383333206176758px; background-color: #ffffff;">架构师通常没有对为其项目工作的他人的直接管理权。他们的项目往往是跨部门的，也可能会跨好多个行业单位。由于不能直接管理他人，所以架构师指示别人或群体完成特定行动的能力就受到限制。他们唯一真正有效的手段就是其影响力。靠技术晋级的人主要关注在技术性的专业知识上。成为技术专家，沟通技术知识对于他们往上爬来说是非常关键的技能。这种技能通常意味着维护你的职位，明确特定项目的潜在风险和当前问题。在单位等级结构的这一层上，你应该阻止产生问题、寻找问题并且解决问题。你的上级都在盯着看你的每一步动作。压力往往会非常大。对于靠技术吃饭的人来说，若想迈出跳至管理的第一步（我认为架构师已经在进行部分管理工作了），阶梯上的下个台阶的特性已经大大变化了。尤其是，首先要求的技能是沟通范围、数量大大地拓宽了。</div><div style="margin: 0px; border: 0px; outline: 0px; font-family: 'Lucida Grande', 'Lucida Sans Unicode', Arial, Verdana, sans-serif; line-height: 22.383333206176758px; background-color: #ffffff;"></div><div style="margin: 0px; border: 0px; outline: 0px; font-family: 'Lucida Grande', 'Lucida Sans Unicode', Arial, Verdana, sans-serif; line-height: 22.383333206176758px; background-color: #ffffff;"><strong style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">架构师必备的关键软技能：沟通</strong></div><div style="margin: 0px; border: 0px; outline: 0px; font-family: 'Lucida Grande', 'Lucida Sans Unicode', Arial, Verdana, sans-serif; line-height: 22.383333206176758px; background-color: #ffffff;"><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;"><img wp-image-12381=""  aligncenter"="" title="架构师的沟通首先基于沟通原则，其次是沟通策略，在此之上是与执行官的有效沟通" src="http://www.programmer.com.cn/wp-content/uploads/2012/07/11.jpg" alt="" width="395" height="278" style="margin: 0px auto; padding: 0px; border: none; outline: 0px; display: block;" /></p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;"><span style="margin: 0px; padding: 0px; border: 0px; outline: 0px; color: #888888;"><strong style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">架构师的沟通首先基于沟通原则，其次是沟通策略，在此之上是与执行官的有效沟通。</strong></span></p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;"><strong style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">一、沟通原则</strong></p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;">学习有效沟通是一个终身的过程&#8212;&#8212;永远都有改善的余地。<span style="margin: 0px; padding: 0px; border: 0px; outline: 0px; font-family: 宋体;">要学习的沟通原则包括：先听后说、专心致志（人和心思在一处）、正面思考等，</span>这些原则有助于建立与别人的信任关系，使你成为更高超的沟通者。</p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;"><img size-full=""  wp-image-12382"="" title="要学习的沟通原则包括：先听后说、专心致志（人和心思在一处）、正面思考等， 这些原则有助于建立与别人的信任关系，使你成为更高超的沟通者" src="http://www.programmer.com.cn/wp-content/uploads/2012/07/21.jpg" alt="" width="430" height="242" style="margin: 0px auto; padding: 0px; border: none; outline: 0px; display: block;" /></p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;"><strong style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">1.<span style="margin: 0px; padding: 0px; border: 0px; outline: 0px; font-family: 宋体;">先听后说</span></strong></p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;">你有没有发现自己在某次谈话中总是想寻求一次讲话的机会，而没有真正在听别人说什么？当你没有听时，你传递给那个对你讲话的人什么信息呢？</p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;">至少表面上，你显得不在乎别人说什么。大部分人会很快厌倦这样的谈话，因为他们说的话白白在空气中传播却没人去听。说话的人也许会想他还有更好的事要做，而结束此次谈话。如果你只是偶尔这样做，这种行为没什么大不了的。如果这是你的习惯做法，那么你是在自己与别人之间构筑一道墙。</p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;">你听的时候，是不是在找机会纠正对方？即便谈论的话题在往前走，但是你的思路还停留在刚才的某一点上？</p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;">这种情况说明，我们并没有在听别人说什么。讲话的人对你很在乎，从其忙碌的工作中抽出时间，为你提供这些宝贵的信息，所以应该认真去听他说什么。</p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;">当有人与你说话时，要看着他说，并试着理解他想沟通的内容。给对方足够的时间来表达他的观点，然后再向其询问要澄清的问题。向他表达非语言的反馈，例如点头，让他知道你在关注这次谈话。</p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;">我认为罗马人<span style="margin: 0px; padding: 0px; border: 0px; outline: 0px; font-family: Calibri;">Epictetus</span><span style="margin: 0px; padding: 0px; border: 0px; outline: 0px; font-family: 宋体;">说得好：&#8220;我们有两个耳朵，一个嘴巴，所以我们应该多听少说。&#8221;</span></p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;"><strong style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">2.<span style="margin: 0px; padding: 0px; border: 0px; outline: 0px; font-family: 宋体;">专心致志</span></strong></p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;">不管你在哪里，都应专心致志。生活中有许多事情要分神，例如这个周末你要做什么，几分钟前开会回来如何解决会上的问题，怎样找个办法告诉老板某个负面的消息，小孩今晚的英式足球比赛几点开场&#8230;&#8230;所有这些琐事都很容易让你想入非非。</p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;">一般来说，人在任何时刻最多只能同时处理<span style="margin: 0px; padding: 0px; border: 0px; outline: 0px; font-family: Calibri;">7</span><span style="margin: 0px; padding: 0px; border: 0px; outline: 0px; font-family: 宋体;">件&#177;</span><span style="margin: 0px; padding: 0px; border: 0px; outline: 0px; font-family: Calibri;">2</span><span style="margin: 0px; padding: 0px; border: 0px; outline: 0px; font-family: 宋体;">件那么多的事。如果你的脑袋全是一些无关紧要的琐事，你就无法专心致志地做事。要是有人对你说话，你就会完全听不到他在讲什么。倘若他在问你问题，你可能要他们再说一遍。这种情况下，你其实是在浪费别人的时间，他们不会高兴的。如果房间里有个执行官，你就会给人家留下一个持久的坏印象：真是个浪费钱的家伙！</span></p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;">请你读些时间管理方面的书，列出每天需要关注事情的清单计划。在计划中安排好任务的优先级（当天、本周等），并标识每个任务准备投入的时间。这个办法能够让你通过计划安排好每件事，节省你的精力去记忆周围各种正在发生的事。</p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;">如果某个会议不是真的需要你参加，你就不要去；假如确实需要你参加，就一定要去，而且人和心思都花在那里。</p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;">我发现，坐直、将脚放在座位正下方、做笔记、直视正在讲话的人，能够自然而然地全神贯注于会议正在进行的事情，从说话和肢体语言两方面都给人以积极参与的正面印象。</p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;">不管你做什么，都要专心致志！</p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;"><strong style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">3.<span style="margin: 0px; padding: 0px; border: 0px; outline: 0px; font-family: 宋体;">正面思考</span></strong></p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;">当你表达信息时，总有许多种方法去传递它们。信息需要真实和准确，然而表现出其意义的方式可以多种多样。</p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;">你可以以积极意义或消极意义提供信息。你可以基于所期望的结果选择某种方法。也可以采用不偏不倚的方式，不带情绪地列举事实，尽管这通常很难做到。</p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;">从沟通的观点来看，人们容易注意负面的东西。通常负面消息总会带来恐惧（当我感觉恐惧邻近时，我会把它当做&#8220;要求集中精力的行动&#8221;的信号）。</p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;">作为架构师，你需要避免不必要的偏见信息，让别人能够选择他们要关注的信息。你可以提供若干种替代方案，但这些方案应当是客观平等的。你需要察觉可能的办法，而不是为别人留下疑惑。</p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;"><strong style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">4.<span style="margin: 0px; padding: 0px; border: 0px; outline: 0px; font-family: 宋体;">尽早道歉</span></strong></p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;">在一天的事务中，你可能注意到对他人做的某个事情不合适或不正确。记住放下自尊去给受影响的对方道一个歉。向别人诚心道歉并不是好玩或者容易之举，但你可以赢得别人的尊敬，展示你在尽力成长，尝试变得更好的意图。</p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;">如果你道歉，对方就有可能重新审视事情，而原谅你带来的任何苦恼伤痛。有些让人尴尬的事情转而有了积极意义。你与那人的关系就有了增进的机会，而不是就此冷淡。</p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;">人的本能倾向就是让冒犯别人后的情势不了了之。遗憾的是，你可能埋下了让它长大成祸患的种子，以致对你造成长期的影响。被得罪的人可能会耿耿于怀，在很长很长时间内记住这件事。那个人也许会把这件事告诉别人，说你是个什么类型的人。你和此人及周围其他人的交往能力可能大打折扣。最后，或许你已经忘记做过的事，但是对方却没有忘记。</p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;">道歉时，你要清楚地表达出要道歉的是什么，你说的是什么意思。如果你不是诚心道歉，虚假的说辞可能把事情弄得更糟。如果你不能表达诚意，就不要道歉，但你的目标应当是努力与你所交往的人修缮积极的关系。避免让道歉使你向错误的方向发展，限制你的个人成长。</p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;"><strong style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">5.<span style="margin: 0px; padding: 0px; border: 0px; outline: 0px; font-family: 宋体;">不要在缺陷上招致恼羞成怒</span></strong></p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;">当你在开评审会（例如产品概念评估、需求评审、设计评审、代码评审、测试评审、产品发布评审）时，通常会检查出评审项目的一些缺陷。评审项目的作者对于这些暴露出的缺陷当然会感到不自在。</p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;">出于通常的礼貌，一旦在特定领域发现了三四个问题，就不要再过高、过深地批评了。如果你需要指出再多的条目，可以将其写下来，让被困扰的人随后能仔细看到这些要点。否则这些事情会招致对方恼羞成怒。由于被评审人成了众矢之的，在效率上会极大地影响评审的后续进展。</p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;">对于评审，有下列一些有效的办法：</p><ul style="margin: 5px 0px 15px; padding: 0px 0px 0px 20px; border: 0px; outline: 0px;"><li style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">确保对评审项目的关注，而评价不是针对生产或创造评审项目的人或单位。换句话说，评审应针对事物、方法，而不是针对人。</li><li style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">避免用&#8220;你&#8221;、&#8220;你的&#8221;这类个人化的评价。</li><li style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">设法表达你要求修改的原因是想达成什么目标：确定修改与市场策略有关，基于一般的架构原则，抑或是公司或部门的目标？</li><li style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">评审应关注改善评审项目的方法，不仅仅因为没有遵循某个编码指导原则，而是修改后为什么有用。评审项目的人不仅需要知道怎样把事情做得更好，还要知道为什么这种改进是有用的。</li><li style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">找机会说出已做出的工作的积极成分。大多数人被指出暴露的缺陷后，都会非常想要辩解，而找到工作的好的方面能够软化这种态势。所有与会者都应明白，目标是创造优秀的工作成果，每个人都要求用同样的标准&#8212;这是集体的努力。</li><li style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">确保会上的每个人都参与进来。以局外人的身份参加会议是在浪费公司的时间。</li><li style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">模仿你在寻求的行为。拿出当评审你的工作，且结果是&#8220;很好，继续干吧&#8221;时的行为。目标是创造优秀的工作成果并持续改进它。换句话说，不是关于你的事，而是关于如何奋力争取优秀的事。</li><li style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">举止文雅：倘若角色互换，作为被评审人，你希望别人怎样给你反馈意见？</li><li style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">任何问题都应记录在案&#8212;不只是你感兴趣要追踪的事，还包括其他人提出的记录。如果确有一大串条目需要引起注意，可能随后还要再进行一次评审。</li></ul><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;"><strong style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">二、沟通策略</strong></p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;">在我们研究了沟通的核心原则后，现在你可以应用一系列策略来展示恒定、高效的沟通风格。</p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;"><strong style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">1.<span style="margin: 0px; padding: 0px; border: 0px; outline: 0px; font-family: 宋体;">多说&#8220;是&#8221;，少说&#8220;不是&#8221;</span></strong></p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;">架构师经常会被咨询问到某个项目的可行性，并提供从战略到战术的多个替代方案，附带若干成本选项，以使商务伙伴能根据特定项目的投资进行判断。架构师与项目评估团队的角色不是决定要构建什么，而是决定怎样构建。我们试图说出的答案是&#8220;对，我们能构建这个项目，这些是相关的信息&#8221;。产生的信息需要包括诸如所考虑的各种替代方案、项目风险（以及可能的规避策略）、基于的假设条件，以及需要指出的突出问题。我们不是在寻找这样的答案：&#8220;不行，这个项目不可行，但我们能构建另一个项目（通过消除原困难项目中的难题，而代之以我们想构建的那些特性）。&#8221;</p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;"><span style="margin: 0px; padding: 0px; border: 0px; outline: 0px; color: #888888;"><strong style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">关键点：作为架构师，我们要寻求说&#8220;是&#8221;的方法。</strong></span></p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;">但是，如果一个项目或任务不可行，我们需要立即巧妙地指出评估结果、解释原因，并提供替代方案。这通常归结于法律法规、行规等原因，以致&#8220;不&#8221;是正确的回答。当然了，还有其他一些例外情况：提出需求的人是想逃避工作，需求违反了公司的政策，或者你手头有优先级更高的工作，无法让你有足够时间来对需求做出满意的答复。这些情况下，你要清楚地告诉人家你说&#8220;不&#8221;的原因。</p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;">如果执行官要求你做某件事，你要确信这个要求的优先级。如果是高优先级要求，你一定要分析不做其他任务的影响，并反馈给执行官。这将让高一级的经理在确定任务的孰重孰轻时有足够的信息。它也有助于你免于日后陷入两难境地而无法自拔&#8212;如果你不得不解释为什么不让另一位经理知道就耽误了其他重要的任务。学会说&#8220;是&#8221;可以采用多种替代形式。通常，它涉及为某人或某个项目找到继续前行的办法。没有必要你自己来承担任务或需求。也许你可以提供一套合理的替代方案，或者引导提出需求的人找到其他人，后者能够解决项目当前面临的问题。对于需要可行性信息的多数项目而言，最值得期望的方法就是提供一个自助餐式的选项，详细罗列出成本、风险、战略影响以及有效的组合等信息。这种策略让需求者处于决定者的地位，使他可以选取最能产生商业价值的解决方案。提供一组方案供客户和同事选择，这种做法能让你自然而然地与他们建立友好关系。</p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;"><strong style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">2.<span style="margin: 0px; padding: 0px; border: 0px; outline: 0px; font-family: 宋体;">在销售过程中建立起信任关系</span></strong></p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;">想想你上次购买一辆车、盖房或者购置一个大物件的情形。这次购买的成就感或挫折感很大限度上取决于你所打交道的销售员或签约人。销售员总是仔细倾听你想要什么东西，通过提供下列信息，让你能够以决策者的身份决定你想买的东西：</p><ul style="margin: 5px 0px 15px; padding: 0px 0px 0px 20px; border: 0px; outline: 0px;"><li style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">可用的选择方案；</li><li style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">各选择方案的开销；</li><li style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">各选择方案的好处；</li><li style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">各选择方案能够如何组合；</li><li style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">各选择方案涉及的风险；</li><li style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">每种选择方案已知的问题。</li></ul><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;">销售员不大可能强行把你往这个或那个方向引导，但会帮助你理清需求，为你寻找以最低花费得到最高价值的解决方案。为做到这一点，他的自身利益只能退而求其次。通过将你的需求置于第一位，销售员能够建立与你的信任关系。这种信任让你感觉你是在有足够信息的情况下做决定，而他是你的伙伴。当有人问起你新购置的物件时，你很可能不只对这个物品的方方面面滔滔不绝，还会提到那个了不起的销售员，并推荐他给你周围那些想购买类似物件的人，因而又开启了一个销售周期。</p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;">作为架构师，你应当成为那个销售员，值得别人信任。</p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;">3.<span style="margin: 0px; padding: 0px; border: 0px; outline: 0px; font-family: 宋体;">特殊场合才说&#8220;不&#8221;</span></p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;">从架构师的前景来看，只有在若干种情况下你可以简单地说&#8220;不&#8221;。大多数时候，你必须提供能让事情完成的替代方案（涉及费用、风险和每种方法的好处）。最后的决定取决于项目的主人（即掌握购买权的人）。</p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;">在其他时候，说&#8220;不&#8221;是合适的（如图<span style="margin: 0px; padding: 0px; border: 0px; outline: 0px; font-family: Calibri;">3</span><span style="margin: 0px; padding: 0px; border: 0px; outline: 0px; font-family: 宋体;">所示）。通常这种拒绝需要有足够合理的深度来支撑，以应付所有必要的质疑。争论的领域很可能与任何项目都存在的关键限制因素有关，如效果、成本、时间和范围。</span></p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;"><span style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">爱惜你的&#8220;不&#8221;，而只把它用到礼仪场合&#8212;&#8212;不要轻易用它。</span></p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;">下面是说&#8220;不&#8221;和不说&#8220;不&#8221;的一些考虑因素：</p><ul style="margin: 5px 0px 15px; padding: 0px 0px 0px 20px; border: 0px; outline: 0px;"><li style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">对于项目的最后期限，当要求违反&#8220;物理法则&#8221;，即无法执行项目给定最后期限内的所有步骤（例如：硬件的获取和供应、规划、开发、要求的培训、测试、修正错误和部署）时，说&#8220;不&#8221;是可接受的。但不能因为工作看起来困难、你不大喜欢它或者有其他不能同时进行的优先级（也许当前需求会很快成为最高优先级&#8212;值得将此列为一个风险）。中性地陈述各竞争优先级的任务，从而让执行官能根据各自的相对重要性安排它们。</li></ul><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;">问自己这些问题：</p><ul style="margin: 5px 0px 15px; padding: 0px 0px 0px 20px; border: 0px; outline: 0px;"><li style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">我表现正直吗？我在会议上公开说的话与我在门廊中说的话一致吗？如果你真的对需求有疑问，应当将它们摆到台面上，即便对你并没有什么好处。与通常一样，这种行动应当以文雅、令人尊敬的方式做出。</li><li style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">有没有替代方案能消除&#8220;物理法则&#8221;问题？脱开思维框框的束缚。如果这是你的公司，你如何解决问题？（当然了，答案不是解雇你周围的所有人。）如果你在特定领域中没有专业知识，你能引入有这方面专业知识的外包人员吗？其他人有没有解决过类似问题？你能将他引入项目，或者至少请教他一些问题吗？是否有一些概念证明能迅速实施来降低项目在某些地方的风险？你需要更多的时间来评估项目吗？</li><li style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">有没有其他人可以和你一起进行头脑风暴，以找出解决方案？</li><li style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">你能分阶段定义项目，每阶段都有可发布的东西（主要的发布）吗？这个分阶段的办法使你能够分别为每个阶段寻求资金，也能够定位你首先要了解什么内容。随着你了解情况的深入，你可以评估下一个阶段，倘若发现下一阶段并不可行，或者不能提供足够商业价值来继续推进的话，你可能退出项目。</li><li style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">如果你不说&#8220;不&#8221;，你可能注定是在&#8220;死亡行军&#8221;（<span style="margin: 0px; padding: 0px; border: 0px; outline: 0px; font-family: Calibri;">death&nbsp;march</span><span style="margin: 0px; padding: 0px; border: 0px; outline: 0px; font-family: 宋体;">）&#8212;&#8212;项目已经有了高度可见性，无休止的加班，客户永远不怎么满意。要求有适当的期望值来避免这种结果。</span></li><li style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">特定的环境有时会影响说&#8220;是&#8221;或&#8220;不&#8221;的决定。例如，在停业期（<span style="margin: 0px; padding: 0px; border: 0px; outline: 0px; font-family: Calibri;">layoff</span><span style="margin: 0px; padding: 0px; border: 0px; outline: 0px; font-family: 宋体;">）或外包（</span><span style="margin: 0px; padding: 0px; border: 0px; outline: 0px; font-family: Calibri;">outsourcing</span><span style="margin: 0px; padding: 0px; border: 0px; outline: 0px; font-family: 宋体;">）期间，可能需要更微妙的方法。每个人在此气氛下都很紧张急躁，项目协商变得很具挑战性。</span></li></ul><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;">只说&#8220;不&#8221;或仅仅阐述事实很难让人接受。充分准备来解释所做决定的原因，证明所做决定是好的商业决定。通过列举事实，探究事实背后的根本原因，陈述此根本原因如何支持期望的商业目标。</p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;">作为架构师，你就是在推销东西。你需要准备即便出现问题，也要将解决方案推销出去。人们提出问题时，可能看上去与你在作对，而实际上，人们询问是为了确认此解决方案，或者他们要了解此解决方案。他们提出问题，是因为他们随后也可能要向他们所在的单位推销这些提及的解决方案。</p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;">你要相信所提到的解决方案。如果你并不真正相信你所推销的东西，你的肢体语言和眼睛会说实话的。你的不诚实如同水中的血腥味那样：你很可能被问及更详细的一些问题，如同鲨鱼在攻击一样。在某种意义上，你是将自己置身于未曾准备好的问题。你需要了解足够多的细节来相信这种解决方案。在你向人们提出某种解决方案时，你也需要自我提问和回答有关的难题。</p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;">在所有可能情况下，避免真的说&#8220;不&#8221;。事实上，根据你所交互的人或群体的语境，解释决定所基于的原因。</p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;"><strong style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">4.<span style="margin: 0px; padding: 0px; border: 0px; outline: 0px; font-family: 宋体;">抑制想自卫的冲动</span></strong></p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;">通常在交谈中，当我们听到并不完全对自己有正面意义的事情时，我们可能会找借口，我们可能会找办法转移话题，并责怪他人，以使自己脱离干系。或者我们想强词夺理，以阐述那些语句。应当避免做出此反应的冲动。相反，代之以等待，并接受别人所说的话。</p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;">在上一段描述的反应中，会谈的真正兴趣已经从对别人转移到你身上。听别人说话的行为至少暂时结束了，我们开始与会谈者发出警示信号：&#8220;我们把话题引向另一个方向吧，一个和我没关系的方向。&#8221;注意你正在用的肢体语言&#8212;胳膊交叉在胸前，或者头转向一边告诉别人&#8220;我不想听了&#8221;。</p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;">问自己这个问题：我能从这个人说的话中学到什么？&#8221;通常，他给出的信息也许并不是你乐意听到的，但其动机是好的，仍是你接受信息并获得个人成长的机会。</p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;">抑制想自卫的冲动的一个例外就是当手头的问题涉及企业政策或你的正直时。如果别人说的话使你真正涉及与公司政策冲突或你出于正直未做某事（假如，你已经正确做出了行动）时，你需要立即抨击这些说法。你可能想用澄清问题的办法来明确要点，比如&#8220;你的意思是我做过某事吗&#8221;。如果别人说&#8220;是的&#8221;，你就以&#8220;这并不准确&#8221;来明确回应；倘若人家回答&#8220;不是&#8221;，要感谢他澄清了此事。</p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;"><strong style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">5.<span style="margin: 0px; padding: 0px; border: 0px; outline: 0px; font-family: 宋体;">倾听建议来改善合作</span></strong></p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;">先寻求理解别人，再寻求被人理解。&#8212;&#8212;作家、演讲家<span style="margin: 0px; padding: 0px; border: 0px; outline: 0px; font-family: Calibri;">Stephen&nbsp;Covey</span></p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;">从软件开发的角度看，批评别人和被批评的情况经常发生。因为有软件评审、设计评审、架构方法评审、单元测试、功能测试、缺陷跟踪，或者只是简单地向别人寻求帮助，与上司一对一地谈话，这个列表不断在进行。在所有情况下，总有机会将别人说的话特定到你身上。</p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;">一旦你把谈话话题转移到自己身上，而不是工作成果或某些事件上，你本能的自卫意识就来了。这时，你听进去任何事情的能力就变得有限，&#8220;要么拼命，要么逃跑&#8221;的本能反应开始占据上风，而你的大脑指挥身体开始变得激动，以准备自我保护。所沟通的用于改善工作成果的有价值信息烟消云散。从商业角度看，将一项工作产品做得尽可能优秀以符合每个人的最大利益，因为我们越能为产品增加价值，公司越有机会从投资中得到回报。</p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;">如果你能避免在谈话中个人化，你听取别人说话的能力就大大提升了。要试着找出他说话的真正用意（即便你不同意他说的话）。以适当的方式取得他想传递的本意，复述一遍要点。一般情况下，别人只是想被理解，他并不是在寻求你同意他的观点。当你倾听并能理解对方表达的要点时，你就能和他心灵相通。</p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;"><span style="margin: 0px; padding: 0px; border: 0px; outline: 0px; color: #888888;"><strong style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">关键点：通过倾听并复述所说过的话，来理清自己的理解。</strong></span></p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;"><strong style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">6.<span style="margin: 0px; padding: 0px; border: 0px; outline: 0px; font-family: 宋体;">了解别人和自己的沟通需求</span></strong></p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;">在架构师的世界中，你需要例行地与许多人交流。你可能在上一次会议上与有些人谈过话，也可能没有和这些人谈话。挑战就是快速了解人们在说什么，他们怎么说这些话，来&#8220;读懂&#8221;本次会议。</p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;">观察关键的时刻，即做出决定的时刻是一个要点，以此识别人们提出的问题和关心的地方，来加强核心概念，帮助你关注会议的方向以及把会议引向一个成功的结论。为了认识这些关键时刻，我们需要吸收所有信息，包括提供给我们的语言或非语言信息。</p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;">观察别人的举止能够告诉我们如何与每个人最好地沟通。由于每个人都不相同，并且对沟通也有不同的需求，架构师必须让传递信息的方式适应这些需求，以确保有效沟通。</p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;">关键点就是我们要基于每个听众成员的沟通需求来匹配交流风格。有些人的反应是能够看出来的，他们的偏好能够用诸如&#8220;我明白你的意思&#8221;之类的话辨别。另外有些人需要倾听，并吸纳语言细节，他们的偏好能够用诸如&#8220;我在听你说&#8221;之类的话辨别。还有一些人在交谈中比较情绪化，他们的偏好能够用诸如&#8220;我觉得怎样怎样&#8221;之类的话辨别。</p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;">除此之外，大部分人的肢体语言（如无精打采、坐姿端正、胳膊交叉、与别人交谈，或者说话时用手势）都能给你关于此人的线索，表明此人在本次会议或集会上是专心致志还是心不在焉的。事实上，电话会议的一个主要麻烦就是你无法看到电话另一端人们的肢体语言。后果就是你不能取得同样多的反馈信息来帮助引导会谈。而一般会谈中很容易看出需要谈到或考察的问题、人们关心的地方及思路。如果仔细倾听，你还是能够从与会者的语音、语调及说话的速度等方面观察出端倪&#8212;来自所有这些方面的反馈有助于了解沟通的效果。</p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;">电话会议的另一个挑战就是你可能不了解电话另一端的所有人，也无法琢磨其沟通方式、语境。要克服这类知识的匮乏，应在会议开始时做到下列事情：</p><ul style="margin: 5px 0px 15px; padding: 0px 0px 0px 20px; border: 0px; outline: 0px;"><li style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">收集电话另一端所有人的名字。</li><li style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">重视每个人的响应。</li><li style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">注意所有与会者的交流方式、开会的方法（如态度、言辞、语调）及角色。</li><li style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">在将来的电话会议上使用这些知识来引导交互过程。</li></ul><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;">诸如<span style="margin: 0px; padding: 0px; border: 0px; outline: 0px; font-family: Calibri;">WebEx</span><span style="margin: 0px; padding: 0px; border: 0px; outline: 0px; font-family: 宋体;">之类的在线开会，比电话会议效果好，至少你能够看到他人当前如何反应。这些可视性也有助于主导会谈。</span></p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;">在视频会议中，每个人都能看到自己，这是对电话会议或在线会议的重大改进。我们能够看到活生生的对方，或者说是某个人的图像，使得交互更具人性化，能够大大改善与其他参会者的沟通能力。</p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;">要记住这种交谈的一个关键方面就是，在交谈中别人不仅以多种方式将他们的所思所想告诉你，你也在给他们传递类似的信息<span style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">。在会议中，你需要本能地意识到你的身体正在给别人传递信息。</span></p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;"><img size-full=""  wp-image-12384"="" title="肢体语言" src="http://www.programmer.com.cn/wp-content/uploads/2012/07/2-4.jpg" alt="" width="257" height="157" style="margin: 0px auto; padding: 0px; border: none; outline: 0px; display: block;" /></p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;"><span style="margin: 0px; padding: 0px; border: 0px; outline: 0px; color: #888888;"><strong style="margin: 0px; padding: 0px; border: 0px; outline: 0px;"><span style="margin: 0px; padding: 0px; border: 0px; outline: 0px; font-family: 宋体;">你的肢体语言会&#8220;大声说话&#8221;&#8212;所以要谨慎你&#8220;说&#8221;的内容</span></strong></span></p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;">在会议中记住这些事项：</p><ul style="margin: 5px 0px 15px; padding: 0px 0px 0px 20px; border: 0px; outline: 0px;"><li style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">你在微笑吗？</li><li style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">你坐姿端正吗？</li><li style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">你赞成时点头吗？</li><li style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">你的眼神对着正在讲话的人吗？</li><li style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">你的声音或者说语调是抑扬顿挫的吗？</li><li style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">你参加会议时的装束风格和别人类似吗？</li><li style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">你真的在倾听并理解别人说的话吗？</li><li style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">你做笔记吗？</li><li style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">你主张对抗吗？</li></ul><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;">所有这些条目组合在一起，可以让别人知道或确认你要发出的消息的一致性。你是在笑着讲述一个伤心的故事吗？如果是这样，这种不一致性就会剥夺你所试图发出消息的完整性。</p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;">对于同样的一个消息，要努力发展自己说什么、怎么说的技巧。这种持之以恒的表现会增强你有效沟通的能力。</p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;"><strong style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">7.<span style="margin: 0px; padding: 0px; border: 0px; outline: 0px; font-family: 宋体;">才思敏捷</span></strong></p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;">随时准备好回答别人的提问。当人们提问时，不大可能先给出预告。也就是说，你不会有任何时间去准备理由充分的答案。问题可能来自任何方面（单位中职务比你高的、和你平级的或者低于你的）。</p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;">作为架构师，你需要对迅速切换语境游刃有余，即记住头脑中每个活跃的事情，将其压入要记忆的栈中，然后集中全部注意力来快速处理面前的语境。这种活动称作&#8220;才思敏捷&#8221;。</p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;">在这种情况发生时，试用下列模式来处理此形势：</p><ul style="margin: 5px 0px 15px; padding: 0px 0px 0px 20px; border: 0px; outline: 0px;"><li style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">关注是谁在问此问题。这个人的背景如何？他需要知道什么信息来理解你的反应？倘若你对他的问题有所反应，这是否合适？</li><li style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">想出三点解释，如果可能的话，包含一条支持这些解释的商业根本原因。在你有限的时间里，试着对你要沟通的答案构想出一幅场景。</li><li style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">如果对方要求你做出某个决定，暂停并思考你要说的话对单位的影响。因为这项决定将在单位中贯彻，别的群体将如何反应？</li><li style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">如果你已经安抚寻求决定的人，也清楚地知道其他群体将对决定的影响有所反应，你应当认识到不久后的日程上将有一系列不令人愉快的会谈。</li><li style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">你也许在考虑做出一项决定，这一决定会导致涉及的每个组都不太高兴。通常，如果你能做到这一点，你就是协商的高手。当每个人在这场游戏中都有利益关系时，所有参与方会在未来更好地合作。如果没有相关的利益，他们会认为自己并未被挑选出来，现在可以集中精力解决手头的现实问题。</li><li style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">有意思的是，在这个所有人都不太高兴的时刻，每个人都变得更通情达理，想出更多的可替代方案来使问题以更简单、更快速、更省钱的方式解决。当答案浮出水面时&#8212;可能是真正革新型的解决方案，就准备说&#8220;是&#8221;吧。</li><li style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">如果你的答案有消极影响，要展示别的答案也是&#8220;有问题&#8221;的。陈词滥调过后，大家同病相怜&#8212;一起共享不快，滋味总比吞咽药丸感觉好一些。</li></ul><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;">当然了，能让每个利益相关者高兴的决定有时可能存在的，也总是最可取的。</p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;"><strong style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">三、与执行官沟通</strong></p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;">执行官在任何公司都是独特的个人。他们的职责很广。执行官的沟通能力、领导才能和关系技能都经过刻苦磨炼。学习与执行官沟通需要花费时间和经过实践，但你只有一次机会来取得第一印象，所以务必准备好。</p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;"><strong style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">1.<span style="margin: 0px; padding: 0px; border: 0px; outline: 0px; font-family: 宋体;">执行官需要信任、忠诚和连贯性</span></strong></p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;">执行官对信任、忠诚和连贯性有着热切的渴望<span style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">。<img size-full=""  wp-image-12385"="" title="执行官" src="http://www.programmer.com.cn/wp-content/uploads/2012/07/2-5.jpg" alt="" width="472" height="287" style="margin: 0px auto; padding: 0px; border: none; outline: 0px; display: block;" /></span></p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;">当你在与执行官沟通时（特别是那些对你工作领域不甚了解的执行官），你需要注重与之建立信任和忠诚关系。在你继续与之工作的过程中，你给出的信息应当具备一致性：你不能某天告诉高级经理一个故事，而第二天却是个完全不同的故事。不要对呈交的信息有偏见，以显得你是对的，而别人不好。关心的事实应尽可能简洁且开门见山，要知道执行官都是一些大忙人。</p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;">当你会见执行官时，不要嘲笑那些不在场的人。这样的行为只能证明你不值得信任，也不够忠诚。</p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;">当你呈交信息时，提供事实，而不是关于人们的观点。事实是能够理性处理的东西，即便是不在场的人也能够理性处理事实。要确保你适当地传递了信息，这样当执行官向有关人员索要事实信息时，即便原先不在场的人也不会措手不及。</p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;">我曾经有过一些这样的参加会议的经历，执行官召集其他的人一起进入房间讨论，来验证我所给出的所有信息。要确保你讲的故事是想在别人面前重复的，因为你可能有机会立即这么做。</p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;"><strong style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">2.<span style="margin: 0px; padding: 0px; border: 0px; outline: 0px; font-family: 宋体;">清晰性甚于完整性</span></strong></p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;">作为一般性的经验方法，给人提供细节信息的数量应当反比于此人在单位中的级别。换句话说，开发者可能需要海量的信息来构建某个东西，而执行官在项目定期更新状态时，只需要有关项目的高度概括性信息。但信息需要清晰、简明扼要。你需要给执行官提供正确的信息，并提供适当的背景，多些商务信息的成分，少些技术信息的成分。</p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;">执行官不大可能会顾及所有技术信息。他们想知道你精通技术，但他们没有时间关心所有的项目细节。这样过滤的一个主要原因就是执行官受时间限制，必须工作于信任的基础上。他们寻求将所有权、执行权和照看项目的责任委派给你。他们希望你处理问题、做好规划，以及照顾项目的其他方方面面。</p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;">执行官想知道的就是如下这些东西：</p><ul style="margin: 5px 0px 15px; padding: 0px 0px 0px 20px; border: 0px; outline: 0px;"><li style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">有哪些风险会导致项目无法如期完成或者按预算完成？风险是否已得到控制？</li><li style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">能创造什么战略资产来支持当前或未来项目的需要？</li><li style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">单位中谁是&#8220;升起的新星&#8221;？</li></ul><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;">执行官要求你提供的是准确的信息。他们希望你保持一致性。一旦你给出一个答案，就应坚持它，所以要谨慎选择你的答案。有的执行官可能会深入项目的特定方面。你至少应该准备探索这方面。执行官可能借此找出你知识的边界及疏忽在哪里。开会时，倘若你处于你不知道或不确信某些信息的境地，要明确表达自己不知道，但声明自己随后会关注被问及的这些信息。永远记住：如果你不这样做，你可能会将自己辛苦挣得的信任关系付诸东流。</p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;">你和执行官最好的交互过程就是把你的扑克牌都放在桌面上。也就是说，让他们能看清你所有的东西（好的、坏的、丑的）。你可能因为彻底袒露、容易被人挑刺而感觉不踏实。但这样的行为能让你在信任和忠诚方面&#8212;这是执行官最看重的&#8212;&#8212;增加好感。</p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;">当你真正需要执行官来介入处理事情时，你已经建立了与之关键的关系，这使你能够与高级经理一起处理这些事情。执行官不想知道的就是项目中存在的争执。部门<span style="margin: 0px; padding: 0px; border: 0px; outline: 0px; font-family: Calibri;">A</span><span style="margin: 0px; padding: 0px; border: 0px; outline: 0px; font-family: 宋体;">与部门</span><span style="margin: 0px; padding: 0px; border: 0px; outline: 0px; font-family: Calibri;">B</span><span style="margin: 0px; padding: 0px; border: 0px; outline: 0px; font-family: 宋体;">之间的分歧完全是&#8220;你的&#8221;问题，你应该去解决它。如果你请执行官来介入&#8220;解决&#8221;某个争端，你和所涉及的团队都不会对后果感到高兴。执行官似乎有第六感，他会选择争端中最痛苦的解决方案。既然如此，建议你简明扼要，并坚持在符合执行官而非</span><span style="margin: 0px; padding: 0px; border: 0px; outline: 0px; font-family: Calibri;">IT</span><span style="margin: 0px; padding: 0px; border: 0px; outline: 0px; font-family: 宋体;">人员需要的层次上解释相关的事实。</span></p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;"><strong style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">3.<span style="margin: 0px; padding: 0px; border: 0px; outline: 0px; font-family: 宋体;">不要让执行官感到惊讶</span></strong></p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;">谈到不断积累的问题时，执行官不喜欢惊讶，尤其是那种惊讶：他们必须在很短时间做出行动、剩下的选择少之又少，而结果是他们必须将坏消息通知给单位的其他部门<span style="margin: 0px; padding: 0px; border: 0px; outline: 0px;">。</span></p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;"><span style="margin: 0px; padding: 0px; border: 0px; outline: 0px; color: #888888;"><strong style="margin: 0px; padding: 0px; border: 0px; outline: 0px;"><span style="margin: 0px; padding: 0px; border: 0px; outline: 0px; font-family: 宋体;">执行官不喜欢惊讶。如果你有坏消息，就早些告诉他们。</span></strong></span></p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;">绝大多数项目的风险是逐渐累积的。从事或接近项目的参与者知道这些风险。如果仔细倾听，你会知道到处都在反映这些信息。遗憾的是，风险发出的隆隆声并不总能让需要听到的人听见。当人们与高层的管理人员和执行官说话时，他们在本能上会报喜不报忧。结果就是，他们不太想把一些看起来不妙的事情呈递上去。</p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;">中层经理不会在来不及处理风险的情况下，乐意被人将风险暴露给他们的上司或其上司的上司&#8212;那就是，围绕风险的推销问题。如果风险会随时间而膨胀，应尽早暴露出来。通常要有个判断过程来确定何时告诉别人这个生长着的麻烦。没有捷径知道确切的时间。作为一个经验规则，早些暴露远比问题发生为时已晚要好得多，因为后者要迫使高级经理人员和执行官去处理善后事宜。</p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;">如果你发现你的上司或管理人员没有将所需的信息沟通给执行官，你可能需要自己呈递这些信息（倘若你决定采取行动，必须极度小心，也许有些你未意识到的因素导致别人那样做）。当你真的呈送消息时，确信所有中层管理人员都意识到了风险。他们需要有机会拟定行为计划来处理这些风险。这仍然是关于信任和忠诚的问题。</p><p style="margin: 0px 0px 15px; padding: 0px; border: 0px; outline: 0px; text-indent: 28px;">当执行官越早知道存在的风险，他们就越能够成功应付它们，并最大限度地降低负面影响。如果执行官被搞得惊讶，他们不会高兴的。假如你还没有破坏他们对你的信任（你工作非常努力才换来的信任），你可能已经在朝这个方向做了。当晋升机会到来时，你可能不会得到执行官的多少支持，因为你曾经引起他的不快。</p></div><img src ="http://www.cppblog.com/HappySky2046/aggbug/195990.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/HappySky2046/" target="_blank">探路者</a> 2012-12-04 23:30 <a href="http://www.cppblog.com/HappySky2046/articles/195990.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>公司领导简写</title><link>http://www.cppblog.com/HappySky2046/articles/186003.html</link><dc:creator>探路者</dc:creator><author>探路者</author><pubDate>Thu, 02 Aug 2012 02:43:00 GMT</pubDate><guid>http://www.cppblog.com/HappySky2046/articles/186003.html</guid><wfw:comment>http://www.cppblog.com/HappySky2046/comments/186003.html</wfw:comment><comments>http://www.cppblog.com/HappySky2046/articles/186003.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/HappySky2046/comments/commentRss/186003.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/HappySky2046/services/trackbacks/186003.html</trackback:ping><description><![CDATA[<span style="font-family: 宋体, Arial, sans-serif; line-height: 20px; ">CEO：Chief Executive Officer 首席执行官&nbsp;</span><br style="font-family: 宋体, Arial, sans-serif; font-size: 12px; margin: 0px; padding: 0px; line-height: 20px; " /><span style="font-family: 宋体, Arial, sans-serif; line-height: 20px; ">CFO：Chief Financial Officer 首席财务官&nbsp;</span><br style="font-family: 宋体, Arial, sans-serif; font-size: 12px; margin: 0px; padding: 0px; line-height: 20px; " /><span style="font-family: 宋体, Arial, sans-serif; line-height: 20px; ">COO：Chief Operated Officer 首席运营官&nbsp;</span><br style="font-family: 宋体, Arial, sans-serif; font-size: 12px; margin: 0px; padding: 0px; line-height: 20px; " /><span style="font-family: 宋体, Arial, sans-serif; line-height: 20px; ">CTO：Chief Technology Officer 首席技术官&nbsp;</span><br style="font-family: 宋体, Arial, sans-serif; font-size: 12px; margin: 0px; padding: 0px; line-height: 20px; " /><span style="font-family: 宋体, Arial, sans-serif; line-height: 20px; ">CIO：Chief Information Officer 首席信息官&nbsp;</span><br style="font-family: 宋体, Arial, sans-serif; font-size: 12px; margin: 0px; padding: 0px; line-height: 20px; " /><span style="font-family: 宋体, Arial, sans-serif; line-height: 20px; ">CRO：Chief Risk Officer 首席风险官</span>&nbsp;<br /><span style="font-family: 宋体, Arial, sans-serif; line-height: 20px; ">VP: Vice president 副总裁</span>&nbsp;<br /><span style="font-family: 宋体, Arial, sans-serif; line-height: 20px; ">VP，</span>
<span style="font-family: 宋体, Arial, sans-serif; line-height: 20px; ">Executive</span>&nbsp;<span style="font-family: 宋体, Arial, sans-serif; line-height: 20px; ">&nbsp;执行副总裁&nbsp;</span><br style="font-family: 宋体, Arial, sans-serif; font-size: 12px; margin: 0px; padding: 0px; line-height: 20px; " /><span style="font-family: 宋体, Arial, sans-serif; line-height: 20px; ">VP, Marketing &nbsp; 副总裁，分管营销&nbsp;</span><br style="font-family: 宋体, Arial, sans-serif; font-size: 12px; margin: 0px; padding: 0px; line-height: 20px; " /><span style="font-family: 宋体, Arial, sans-serif; line-height: 20px; ">VP, International Business 副总裁，分管国际业务&nbsp;</span><br style="font-family: 宋体, Arial, sans-serif; font-size: 12px; margin: 0px; padding: 0px; line-height: 20px; " /><span style="font-family: 宋体, Arial, sans-serif; line-height: 20px; ">VP，AP Region 副总裁，分管亚太区&nbsp;</span>&nbsp;<br /><pre id="best-answer-content"  mb10"="" data-accusearea="aContent" style="margin-top: 0px; margin-bottom: 10px; padding: 0px; font-family: Arial; white-space: pre-wrap; word-wrap: break-word; zoom: 1; line-height: 22px; background-color: #fffcf6; ">GM(General Manager)                  总经理</pre><pre id="best-answer-content"  mb10"="" data-accusearea="aContent" style="margin-top: 0px; margin-bottom: 10px; padding: 0px; font-family: Arial; white-space: pre-wrap; word-wrap: break-word; zoom: 1; line-height: 22px; background-color: #fffcf6; ">HRD(Human Resource Director)   人力资源总监  <br />OD(Operations Director)               运营总监  <br />MD(Marketing Director)                 市场总监  <br />OM(Operations Manager)             运作经理  <br />PM(Production Manager)              生产经理  <br />(Product Manager)                        产品经理 </pre><img src ="http://www.cppblog.com/HappySky2046/aggbug/186003.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/HappySky2046/" target="_blank">探路者</a> 2012-08-02 10:43 <a href="http://www.cppblog.com/HappySky2046/articles/186003.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>企业级系统架构</title><link>http://www.cppblog.com/HappySky2046/articles/185916.html</link><dc:creator>探路者</dc:creator><author>探路者</author><pubDate>Wed, 01 Aug 2012 09:20:00 GMT</pubDate><guid>http://www.cppblog.com/HappySky2046/articles/185916.html</guid><description><![CDATA[<p style="padding: 0px; font-family: 'Microsoft Yahei'; text-align: left; background-color: #f5f5f5; ">在我们刚开始学习架构的时候，首先会想到分层的概念，分层架构比较经典的是三层架构，那么，什么是三层架构呢？它包括表现层，业务层，数据访问层；而对于一个新手来说，从抽象意义上的三层架构，逻辑上就划分为三个层。</p><p style="padding: 0px; font-family: 'Microsoft Yahei'; text-align: left; background-color: #f5f5f5; "><a href="http://images.cnblogs.com/cnblogs_com/liping13599168/201105/201105111417022182.png" style="margin: 0px; padding: 0px; color: #0069d6; line-height: inherit; "><img title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/liping13599168/201105/201105111417034658.png" width="210" height="359" style="margin: 0px; padding: 0px; border: 0px; background-image: none; display: inline; " /></a></p><p style="padding: 0px; font-family: 'Microsoft Yahei'; text-align: left; background-color: #f5f5f5; ">这个是最基本的三层架构模式。</p><p style="padding: 0px; font-family: 'Microsoft Yahei'; text-align: left; background-color: #f5f5f5; "><strong style="margin: 0px; padding: 0px; ">表现层</strong>充当系统的界面呈现以及UI逻辑的角色，也就是说，UI（用户界面）属于表现层；</p><p style="padding: 0px; font-family: 'Microsoft Yahei'; text-align: left; background-color: #f5f5f5; ">举一个对于asp.net WebForm来说，人们喜欢把对于UI的控制逻辑（服务器控件的读取、设置、事件等等）写在页面的后置隐藏代码中，并且依赖业务逻辑层。当然，服务器控件支持数据绑定的功能，可以通过数据源进行绑定控件。这样就可以节省在后置隐藏中的代码。</p><p style="padding: 0px; font-family: 'Microsoft Yahei'; text-align: left; background-color: #f5f5f5; ">&nbsp;</p><p style="padding: 0px; font-family: 'Microsoft Yahei'; text-align: left; background-color: #f5f5f5; ">因此，我们就可以把表现层分为UI用户界面以及UI逻辑：</p><p style="padding: 0px; font-family: 'Microsoft Yahei'; text-align: left; background-color: #f5f5f5; "><a href="http://images.cnblogs.com/cnblogs_com/liping13599168/201105/201105111417034591.png" style="margin: 0px; padding: 0px; color: #0069d6; line-height: inherit; "><img title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/liping13599168/201105/201105111417033163.png" width="207" height="394" style="margin: 0px; padding: 0px; border: 0px; background-image: none; display: inline; " /></a></p><p style="padding: 0px; font-family: 'Microsoft Yahei'; text-align: left; background-color: #f5f5f5; "><strong style="margin: 0px; padding: 0px; ">UI用户界面的职责</strong>只是作为数据输入和输出后的展示工作。</p><p style="padding: 0px; font-family: 'Microsoft Yahei'; text-align: left; background-color: #f5f5f5; "><strong style="margin: 0px; padding: 0px; ">UI逻辑的职责</strong>是负责业务逻辑层以及UI用户界面之间的数据交互，并且<strong style="margin: 0px; padding: 0px; ">尽可能地让UI逻辑不依赖于UI技术</strong>。</p><p style="padding: 0px; font-family: 'Microsoft Yahei'; text-align: left; background-color: #f5f5f5; ">其中UI用户界面的实现方式有很多，包括ASP.NET，WinForm，WPF，Silverlight，移动Web，智能设备等等。</p><p style="padding: 0px; font-family: 'Microsoft Yahei'; text-align: left; background-color: #f5f5f5; "><a href="http://images.cnblogs.com/cnblogs_com/liping13599168/201105/201105111417041178.png" style="margin: 0px; padding: 0px; color: #0069d6; line-height: inherit; "><img title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/liping13599168/201105/201105111417043969.png" width="503" height="503" style="margin: 0px; padding: 0px; border: 0px; background-image: none; display: inline; " /></a></p><p style="padding: 0px; font-family: 'Microsoft Yahei'; text-align: left; background-color: #f5f5f5; ">将表现层中UI页面和UI逻辑分离的策略中，当前使用最多的两种模式是MVC模式和MVP模式。</p><p style="padding: 0px; font-family: 'Microsoft Yahei'; text-align: left; background-color: #f5f5f5; "><strong style="margin: 0px; padding: 0px; ">MVC模式，即模型-视图-控制器模式</strong>，通过视图触发并执行某个操作，调用控制器，通过控制器去操作业务层，最终返回模型，在视图中进行展示。这里的模型可以是一个领域模型（DM），也可以是一个数据迁移对象（DTO）。</p><p style="padding: 0px; font-family: 'Microsoft Yahei'; text-align: left; background-color: #f5f5f5; "><strong style="margin: 0px; padding: 0px; ">MVP模式，即模型-视图-展示器模式</strong>，和MVC模式有点像，不同的是MVP中视图和模型是被完全分离出来的，视图中定义一个接口，而展示器通过调用该接口的方法以控制视图。因此，<strong style="margin: 0px; padding: 0px; ">视图和模型是松散的，展示器也充当了一个控制器的角色，同时它也不依赖于UI技</strong>术。</p><p style="padding: 0px; font-family: 'Microsoft Yahei'; text-align: left; background-color: #f5f5f5; ">另外再介绍一种模式PM（Preentation Model），它可以说是MVP的变体，在PM中，视图不定义接口，这里的模型只是表示视图状态的类，视图中的元素被直接绑定到模型属性上。例如在WPF中，WPF就先天的具有数据双向绑定机制以及事件通知属性机制。</p><p style="padding: 0px; font-family: 'Microsoft Yahei'; text-align: left; background-color: #f5f5f5; ">所以它特别适用于WPF，Sliverlight等等。</p><p style="padding: 0px; font-family: 'Microsoft Yahei'; text-align: left; background-color: #f5f5f5; "><a href="http://images.cnblogs.com/cnblogs_com/liping13599168/201105/201105111417058014.png" style="margin: 0px; padding: 0px; color: #0069d6; line-height: inherit; "><img title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/liping13599168/201105/201105111417054360.png" width="503" height="587" style="margin: 0px; padding: 0px; border: 0px; background-image: none; display: inline; " /></a></p><p style="padding: 0px; font-family: 'Microsoft Yahei'; text-align: left; background-color: #f5f5f5; ">&nbsp;</p><p style="padding: 0px; font-family: 'Microsoft Yahei'; text-align: left; background-color: #f5f5f5; ">在开始业务层之前,不得不说一个前提,在一个小型项目中,直接让表现层调用业务层,足以解决所有问题。但是，当项目大到使用多种表现形式，如使用了各种UI技术，ASP.NET，WPF，移动设备等等，就要考虑在你的表现层和业务层之间增加一个层，以至于让表现层和业务层解耦，因为业务层作为一个业务中间件的平台，最好不要暴露于表现层中，这个层就是传说中的<strong style="margin: 0px; padding: 0px; ">服务层</strong>。架构图又演化为：</p><p style="padding: 0px; font-family: 'Microsoft Yahei'; text-align: left; background-color: #f5f5f5; "><a href="http://images.cnblogs.com/cnblogs_com/liping13599168/201105/201105111433546719.png" style="margin: 0px; padding: 0px; color: #0069d6; line-height: inherit; "><img title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/liping13599168/201105/20110511143354589.png" width="503" height="707" style="margin: 0px; padding: 0px; border: 0px; background-image: none; display: inline; " /></a></p><p style="padding: 0px; font-family: 'Microsoft Yahei'; text-align: left; background-color: #f5f5f5; ">服务层实际上并不执行任何具体的工作，其功能在于组织各个业务对象,服务层将业务层所有的细节对表现层都隐藏起来,服务器将组织业务逻辑层中的组件,并且通过数据迁移对象(DTO)与表现层交互,因此就产生一个DTO模型。</p><p style="padding: 0px; font-family: 'Microsoft Yahei'; text-align: left; background-color: #f5f5f5; ">为了实现服务的可重用性<strong style="margin: 0px; padding: 0px; ">，需要使用服务接口</strong>，表现层通过规定的接口访问功能。服务的实现继承服务接口，而<strong style="margin: 0px; padding: 0px; ">服务的实现专注于业务层的调用</strong>。</p><p style="padding: 0px; font-family: 'Microsoft Yahei'; text-align: left; background-color: #f5f5f5; "><a href="http://images.cnblogs.com/cnblogs_com/liping13599168/201105/201105111441337657.png" style="margin: 0px; padding: 0px; color: #0069d6; line-height: inherit; "><img title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/liping13599168/201105/201105111441347591.png" width="503" height="695" style="margin: 0px; padding: 0px; border: 0px; background-image: none; display: inline; " /></a></p><p style="padding: 0px; font-family: 'Microsoft Yahei'; text-align: left; background-color: #f5f5f5; ">对于服务层，常用的方法包括Web服务、.NET Remoting、Rest以及WCF技术。</p><p style="padding: 0px; font-family: 'Microsoft Yahei'; text-align: left; background-color: #f5f5f5; ">本人比较建议使用WCF作为服务，因为可以方便地通过配置达到远程调用服务的目的。</p><p style="padding: 0px; font-family: 'Microsoft Yahei'; text-align: left; background-color: #f5f5f5; ">服务层消除了两个表现层和业务层之间的耦合，服务层可以实现一个远程接口，达到多UI技术甚至多平台上的通信。</p><p style="padding: 0px; font-family: 'Microsoft Yahei'; text-align: left; background-color: #f5f5f5; ">当然增加服务层也有缺点，假如使用WCF服务，会增加系统的调用开销，进而影响性能。</p><p style="padding: 0px; font-family: 'Microsoft Yahei'; text-align: left; background-color: #f5f5f5; "><a href="http://images.cnblogs.com/cnblogs_com/liping13599168/201105/201105111451021457.png" style="margin: 0px; padding: 0px; color: #0069d6; line-height: inherit; "><img title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/liping13599168/201105/201105111451021739.png" width="503" height="887" style="margin: 0px; padding: 0px; border: 0px; background-image: none; display: inline; " /></a></p><p style="padding: 0px; font-family: 'Microsoft Yahei'; text-align: left; background-color: #f5f5f5; ">&nbsp;</p><p style="padding: 0px; font-family: 'Microsoft Yahei'; text-align: left; background-color: #f5f5f5; "><strong style="margin: 0px; padding: 0px; ">业务层</strong>中包含系统所需要业务过程上的实现，并与下层的数据访问层交互。</p><p style="padding: 0px; font-family: 'Microsoft Yahei'; text-align: left; background-color: #f5f5f5; ">我们通常也叫做业务层叫做业务逻辑层，但我认为<strong style="margin: 0px; padding: 0px; ">业务逻辑层是属于业务层的一方面</strong>，业务逻辑更专注于业务上逻辑算法的实现。因为业务层还可以包括其他的方面。</p><p style="padding: 0px; font-family: 'Microsoft Yahei'; text-align: left; background-color: #f5f5f5; ">业务层必须包括对业务实体尽心建模的对象模型，表达了客户的所有策略和需求的业务规则，因此就产生了<strong style="margin: 0px; padding: 0px; ">领域模型</strong>。</p><p style="padding: 0px; font-family: 'Microsoft Yahei'; text-align: left; background-color: #f5f5f5; ">（PS：如果这里你不使用领域模型，那么需要采用<strong style="margin: 0px; padding: 0px; ">业务规则层</strong>进行业务功能上的业务规则的验证和控制）</p><p style="padding: 0px; font-family: 'Microsoft Yahei'; text-align: left; background-color: #f5f5f5; ">领域模型包括对实体的属性定义，方法定义以及实体与实体之间的关系。从这个角度上看，UML建模至关重要，通过对UML动态图和静态图的描述，可以映射到领域模型中。</p><p style="padding: 0px; font-family: 'Microsoft Yahei'; text-align: left; background-color: #f5f5f5; ">从服务层刚才讲到了DTO模型，这里需要一个机制将DTO转化为领域模型，所以产生了DTO映射层（DTOMapper）。</p><p style="padding: 0px; font-family: 'Microsoft Yahei'; text-align: left; background-color: #f5f5f5; ">另外业务层还包括核心中间件技术，包括第三方组件，以及工作流引擎等等。</p><p style="padding: 0px; font-family: 'Microsoft Yahei'; text-align: left; background-color: #f5f5f5; "><a href="http://images.cnblogs.com/cnblogs_com/liping13599168/201105/201105111517174507.png" style="margin: 0px; padding: 0px; color: #0069d6; line-height: inherit; "><img title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/liping13599168/201105/201105111517205540.png" width="503" height="1103" style="margin: 0px; padding: 0px; border: 0px; background-image: none; display: inline; " /></a></p><p style="padding: 0px; font-family: 'Microsoft Yahei'; text-align: left; background-color: #f5f5f5; ">&nbsp;</p><p style="padding: 0px; font-family: 'Microsoft Yahei'; text-align: left; background-color: #f5f5f5; ">业务层需要考虑到一些与数据访问层交互的设计模式，模式中包括事物脚本模式、表模块模式、活动记录模式、领域模型模式。</p><p style="padding: 0px; font-family: 'Microsoft Yahei'; text-align: left; background-color: #f5f5f5; "><strong style="margin: 0px; padding: 0px; ">事物脚本模式</strong>是通过方法来执行业务流程，它是一个过程式模型，事物脚本的每个方法都有一个特定的事物脚本，它侧重于业务上一系列流程上的顺序操作，它实现起来很简单，但是它有个致命的缺点就是它会造成很多重复的代码。</p><p style="padding: 0px; font-family: 'Microsoft Yahei'; text-align: left; background-color: #f5f5f5; "><strong style="margin: 0px; padding: 0px; ">表模块模式</strong>比起事物脚本模式，具有一定的结构，它的思想也很简单，每个数据表都定义一个业务组件（实体类，实体操作类），在.NET中更多的使用DataSet作为表模型的数据交互。但是它也有一个缺点就是它是从数据库驱动它不适合于大量的数据表以及数据表之间的复杂关系。</p><p style="padding: 0px; font-family: 'Microsoft Yahei'; text-align: left; background-color: #f5f5f5; "><strong style="margin: 0px; padding: 0px; ">活动记录模式</strong>中的对象中，可以包含数据和方法。它接近于数据表的结构，它的对象中执行方法中可以包含CRUD操作，验证算法，以及其他的计算功能。一般来说，领域模型不是太复杂，活动记录模式是个好选择。当然他也存在问题，同样地，它对于复杂的业务上，维护的成本也很高，并且如果需求变更导致数据库修改，就需要调整记录对象模型中的相关代码。</p><p style="padding: 0px; font-family: 'Microsoft Yahei'; text-align: left; background-color: #f5f5f5; ">经典应用：LINQ-TO-SQL以及Castle ActiveRecord。</p><p style="padding: 0px; font-family: 'Microsoft Yahei'; text-align: left; background-color: #f5f5f5; "><strong style="margin: 0px; padding: 0px; ">领域模型模式</strong>是从领域驱动设计中衍生来的，它是以业务为核心的设计模式。它对于复杂的业务逻辑，相当适用。前三种方式使用的是以数据驱动方式，数据驱动方式特点简单，但是当系统到了一定的规模后，就会到难以维护的程度。</p><p style="padding: 0px; font-family: 'Microsoft Yahei'; text-align: left; background-color: #f5f5f5; "><a href="http://images.cnblogs.com/cnblogs_com/liping13599168/201105/201105111548523016.png" style="margin: 0px; padding: 0px; color: #0069d6; line-height: inherit; "><img title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/liping13599168/201105/201105111548552195.png" width="683" height="1103" style="margin: 0px; padding: 0px; border: 0px; background-image: none; display: inline; " /></a></p><p style="padding: 0px; font-family: 'Microsoft Yahei'; text-align: left; background-color: #f5f5f5; ">&nbsp;</p><p style="padding: 0px; font-family: 'Microsoft Yahei'; text-align: left; background-color: #f5f5f5; "><strong style="margin: 0px; padding: 0px; ">数据访问层</strong>的目的很明确,主要作为提供数据持久化的功能，包括数据的读取和写入，另外还必须包括事务处理，并发控制等等。</p><p style="padding: 0px; font-family: 'Microsoft Yahei'; text-align: left; background-color: #f5f5f5; ">操作数据库的方法可以有两种方式,ORM方式，ADO.NET方式。</p><p style="padding: 0px; font-family: 'Microsoft Yahei'; text-align: left; background-color: #f5f5f5; ">ORM可以采用一些第三方的ORM框架来实现，ADO.NET采用ASP.NET自带的数据库操作来实现。</p><p style="padding: 0px; font-family: 'Microsoft Yahei'; text-align: left; background-color: #f5f5f5; ">不同的数据库具有不同的持久化实现，因此这里添加一个<strong style="margin: 0px; padding: 0px; ">存储仓库接口层</strong>，来适应不同的数据库实现，这里你可以使用IOC依赖注入方式进行数据库选型，可以利用Unity、Spring.NET、Castle的IOC容器等等。</p><p style="padding: 0px; font-family: 'Microsoft Yahei'; text-align: left; background-color: #f5f5f5; "><a href="http://images.cnblogs.com/cnblogs_com/liping13599168/201105/201105111629576861.png" style="margin: 0px; padding: 0px; color: #0069d6; line-height: inherit; "><img title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/liping13599168/201105/201105111629589270.png" width="683" height="1451" style="margin: 0px; padding: 0px; border: 0px; background-image: none; display: inline; " /></a></p><p style="padding: 0px; font-family: 'Microsoft Yahei'; text-align: left; background-color: #f5f5f5; ">&nbsp;</p><p style="padding: 0px; font-family: 'Microsoft Yahei'; text-align: left; background-color: #f5f5f5; ">最后各个层中都可以依赖于<strong style="margin: 0px; padding: 0px; ">公共基础设施层</strong>。</p><p style="padding: 0px; font-family: 'Microsoft Yahei'; text-align: left; background-color: #f5f5f5; "><strong style="margin: 0px; padding: 0px; ">公共基础设施层</strong>可以包括Common通用模块，Logging日志模块，Exception异常模块，Configuration配置模块，DI依赖注入模块，单元测试模块以及第三方组件（例如NHibernate、Sprint.NET、Castle、Quartz计划任务等等）</p><p style="padding: 0px; font-family: 'Microsoft Yahei'; text-align: left; background-color: #f5f5f5; ">最终图：</p><p style="padding: 0px; font-family: 'Microsoft Yahei'; text-align: left; background-color: #f5f5f5; "><a href="http://images.cnblogs.com/cnblogs_com/liping13599168/201105/201105111629584220.png" style="margin: 0px; padding: 0px; color: #0069d6; line-height: inherit; "><img title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/liping13599168/201105/201105111629596629.png" width="863" height="1451" style="margin: 0px; padding: 0px; border: 0px; background-image: none; display: inline; " /></a></p><p style="padding: 0px; font-family: 'Microsoft Yahei'; text-align: left; background-color: #f5f5f5; ">&nbsp;</p><p style="padding: 0px; font-family: 'Microsoft Yahei'; text-align: left; background-color: #f5f5f5; ">总结：项目类型、项目规模以及业务上的需求，都影响着系统架构的设计，系统架构并不是一层不变的，没有最好的架构，只有更好的架构，并且从项目中多思考系统的扩展性。文中对于架构的分析，只是从通常的角度上去考虑，在项目中，您还需要根据实际情况去做调整。<br />出处:&nbsp;<a href="http://www.cnblogs.com/liping13599168/archive/2011/05/11/2043127.html">http://www.cnblogs.com/liping13599168/archive/2011/05/11/2043127.html</a></p><img src ="http://www.cppblog.com/HappySky2046/aggbug/185916.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/HappySky2046/" target="_blank">探路者</a> 2012-08-01 17:20 <a href="http://www.cppblog.com/HappySky2046/articles/185916.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>