溯源微服务:企业分布式应用的一次回顾
微服务作为架构风格几乎成为云时代企业级应用的事实标准,构成微服务的技术元素本身却并非革命性。跨平台的分布式通信框架、地址无关的服务注册与发现、智能路由与编排等技术早已在CORBA、SOA时代实现了一遍又一遍,我们不禁好奇,微服务有什么不同?本文是对企业分布式应用的一次回顾,与前微服务时代相比,我们究竟在哪些领域吸取了教训,哪些方面持续搞砸。
架构的关键在于构造合理的封装抽象。良好的抽象构造如进程,由操作系统接管CPU调度、内存地址空间分配和I/O,程序员的心智从此解放,得以聚焦在业务逻辑上。糟糕的抽象往往引向万丈深渊,大量精力被浪费在抽象泄露带来的问题上。
让我们从组件间的通信开始,最初人们认为这只是需要被解决的技术要素。
关于如何实现跨平台的分布式通信,30年前诞生的CORBA架构在今天来看仍然非常漂亮:通过定义IDL/ORB/API我们可以将内存对象任意分布于网络中。只要共享IDL,对象可以由C++/Java等不同的语言实现,其互相调用就像本地方法一样简单。然而实践经验告诉我们,分布式系统总是会出现本地调用不会发生的各种问题:网络的开销、传输的延迟、消息的超时和丢包、远端系统的崩溃……物理世界的技术约束是无法被忽略的,我们没有办法把分布式调用抽象成简单的本地方法。因此Martin Fowler在他的< 企业应用架构模式>里提出了著名分布式对象第一定律:“不要分布式你的对象”。相反,你应该把尽可能多的操作置于进程之内,通过replicate整个应用的方式来实现系统的scale。
由分析师们发起的SOA运动从另一个角度看待这个问题,Web Service应该是对企业资产和业务能力的封装。我们开始站在更高的维度,远过程调用不再只是技术意义上的集成。WSDL不仅是通信调用的接口,更是服务间的契约;UDDI不仅是服务描述、发现、集成的中心,更是企业业务与服务的黄页。WS-在厂商的裹挟下发展成包罗万象,却也没几个人能掌握。开发者们抱怨花了太多时间写冗余的XML制定所谓的规范,WSDL生成的客户端也将不同服务耦合在一起。是否有更加轻量敏捷的方式,让我们快点开始写第一行生产代码?
于是我们看到REST的兴起。起初是作为反叛,用更加轻量级的方式(http+json)使用Web。然后我们发现”企业级”应用并非需要ESB这样昂贵的专有中间件,由”消费级”技术组成的万维网是世界上最大规模的分布式网络,我们应该向其学习如何构建健壮、可演化的系统。Roy Fielding那篇论文所提出的无状态、可缓存等特征已经深入人心,而狭义上的REST API(基于资源的URI、HTTP动词和状态码的标准接口)也成为API设计的最佳实践。
既然API和网站一样都是基于通用Web技术,API是否可以像网站一样作为产品提供呢(APIs as product)?于是越来越多的企业开始将自己的业务能力封装成API,提供给消费者,随之而来的是更弹性的商业应用和更灵活的计费方式。很多组织也着手构建自己的API市场,把内部IT能力整合、复用,并为孵化外部产品做准备。API已经成为商业价值主张的一部分。
我们从聚焦实现细节的rpc出发,来到了更具价值导向的REST API。即使构建内部系统,以消费者驱动的方式,也总是能帮助我们设计出更加松耦合和易于演进的API。
编程语言中的组件构造(如Java中的jar, C#中的dll)是软件架构师们封装可复用单元的最常用武器。组件作为理论上的最小部署单元,在工程实践中却并不容易独立变更。一般应用程序需要讲多个组件打包成一个部署单元(如war包),链接在内存地址中进行调用。对单个组件的热更新往往对组件间耦合和对象状态管理有很高的要求,重新部署整个应用一般是默认选项。以进程为边界构建可独立部署的服务成为架构师的另一项选择。
早期的服务只是单纯的技术构件,大多数组织从纯粹的技术实现角度考虑服务的划分。SOA的推动者们指出企业的信息资产应该被复用,信息孤岛应该被打通。通过将不同的服务编排组合,我们应该能够实现IT对业务更加灵活的支撑。
SOA的服务建模一般采用业务流程驱动的方式。一个典型的SOA设计是由业务分析师自顶向下地对企业现有业务流程进行分析,通过BPM引擎对流程进行建模,向下分解成组合服务,并进一步拆分成数据访问服务(很多可怜的SOA实现中数据的访问被拆分成不同的读服务和写服务)。然而这带来的问题是,服务跟服务间的耦合非常严重。当我的业务发生了变化,可能会需要修改很多不同的服务,涉及到多个团队的沟通和协调。在运行时层面,服务器间的通信非常频繁,用户在界面上的一次点击按钮,对应的后台多层服务间的级联通信。这给系统性能和稳定性也带来了巨大的挑战。SOA式的服务建模从分析型思维出发,却往往低估了分布式系统和跨团队协调的复杂度,导致服务拆分粒度过细。
微服务的名字常常让人误解,但实施正确的微服务粒度可能并不”微”。Martin Fowler与James Lewis在开创微服务定义的一文中已经指出微服务应该围绕完整的业务能力。今天我们在做微服务设计时,常常利用领域驱动设计中的Bounded Context来进行服务边界的划分。假设你的库存管理是一个独立的业务子域,针对库存的维护和操作应该被放到通过一个上下文和微服务中,由一个团队进行开发维护。多数业务变更都发生在上下文内部,不涉及跨团队协调。单个codebase内的重构和部署让发布更加容易。维护库存所需要的信息查询的调用多发生在进程内,更好的性能,同时无需处理额外的一致性问题。
如今我们对服务的定义已经超越了技术组件,领先的组织已经在尝试将design thinking, business operating model应用到微服务设计中。
即使有了设计合理的服务于API,我们仍然需要与之匹配的工程实践才能将其顺利实施。
今天仍有很多企业使用集中式的应用服务器部署应用:开发团队将软件包构建出来,再统一安装到应用服务器中。对应用团队来说,这往往意味着漫长的反馈周期和痛苦的自动化。我们很早就推荐用Jetty这样内嵌式的应用容器部署软件,启动更快,测试环境更接近生产。one Tomcat per VM的部署方式虽然运行时开销较大,却是前容器时代隔离性最好的服务部署模式。Docker将这个实践更进一步,除了更轻量级的隔离,我们第一次可以将软件和所依赖的环境本身打包成版本化的artifact,彻底统一开发和生产环境。容器技术的成熟让我们可以将部署去中心化,开发团队可以独立部署一个服务。
数据库耦合是影响服务独立变更的另一重要因素。相比代码构成的应用软件,数据库schema更加难以变动。因为难以测试、难以兼顾性能优化和耦合的发布周期等因素,服务间以数据库集成成为臭名昭著的反模式。服务间的集成应该依赖封装好的显示接口,而不是数据库这种实现细节。我们应该在兼顾数据一致性的情况下,为每个微服务分配独立的db schema甚至db instance。如果说十年前数据几乎等同于关系数据库。如今数 据则可能呈现出各种形态:键值、文档、时间序列、图…我们完全可以采用更加合适的技术,以去中心化的方式进行微服务的数据治理。
即使将这一切都解耦,如果将交给一个集中的团队去实施,很有可能最终还是得到一个耦合的架构。这就是是著名的康威定律。康威定律告诉我们“设计系统的架构受制于产生这些设计的组织的沟通结构”。但同样我们可以将康威定律反转应用:如果你想达成一个目标架构,则必须对团队结构进行调整,使之和目标架构对齐。相比单体系统,微服务在运行时监控和运维所带来的挑战更大。”you build it, you run it”的DevOps文化成为必须。监控运维不再是Ops部门的事情,产品团队必须对微服务的整个生命周期负责。授权的去中心化自治团队是实施微服务的必要条件。
我们在很多方向的确取得了进展。但即使在微服务时代,很多问题仍然在轮回发生着,似乎我们总是无法吸取 历史 的教训。让我们看一看那些挥之不去的反模式阴云。
另一个挥之不去的阴影是ESB。ESB在将异构的应用wire在一起有着关键的作用。然而当越来越多的职责被加入:数据报文的裁剪转换、难以测试和版本控制的编排(orchection)逻辑、服务发现智能路由监控治理分布式事务等All in One的solution将ESB变成了一个可怕的单点梦魇。所以微服务发出了“智能终端哑管道”的呐喊:我们只是需要一个不那么智能的代理处理可靠消息传输,将灵活的逻辑交给服务本身去编配(choreography)吧。
于是在典型的微服务架构里,负载均衡、服务注册发现、分布式追踪等组件以Unix way的方式各司其职。然而在利益诱惑和特性竞争压力之下,很多厂商不断将更多的功能放进他们的中间件,其中为代表的Overambitious API gateways俨然要重新实现占据中心的ESB。如果API gateway只是处理鉴权、限流等横切层逻辑没有问题,如果API gateway开始处理数据转换和业务逻辑编排,你应该提高警惕!
尽管行业在不断发展,但很多时候人们仍然沿用旧的思维,用新的技术去一遍遍重新实现这些旧的反模式。
你总是可以在技术雷达里追踪微服务的state of art,如今这个领域的前沿方向是什么,Service Mesh, Chaos Engineering, 还是Observability as Code?然而 历史 告诉我们,新的技术在解决一些问题的同时,也可能会产生新的问题。更糟糕的是,我们永远无法记住 历史 ,用新的工具更高效地重现旧日问题。
Technologies come and go, Principles stay forever。好在那些架构和实践背后的原则是经久不变的。从操作系统到移动应用都会需要高内聚低耦合的架构,任何软件开发都需要版本控制、自动化构建等实践。谨记这些核心原则、谨记软件被创造出来是为了解决有价值的问题,可以帮我们更好的借鉴 历史 的经验,理解和采纳新的技术。
文/ThougtWorks刘尚奇
本文首发于刘尚奇个人网站:https://6up7com/a-retrospective-for-enterprise-distributed-application/
这个问题我也遇到过。我用的是ipad,也收不全。最好我一一排除。
1看协议做错了吗。
2看ipad自身带的客户端是否有过滤邮件的功能。容量一些设置。
3那份要收的邮件是否在收信箱里等原因。
4ipad自定义的时间,是否正常。
最后,我用imap协议搞定。同步。你先用前4条检查应该能搞定。
第一步:将打印机连接至主机,打开打印机电源,通过主机的“控制面板”进入到“打印机和传真”文件夹,在空白处单击鼠标右键,选择“添加打印机”命令,打开添加打印机向导窗口。选择“连接到此计算机的本地打印机”,并勾选“自动检测并安装即插即用的打印机”复选框。
第二步:此时主机将会进行新打印机的检测,很快便会发现已经连接好的打印机,根据提示将打印机附带的驱动程序光盘放入光驱中,安装好打印机的驱动程序后,在“打印机和传真”文件夹内便会出现该打印机的图标了。
第三步:在新安装的打印机图标上单击鼠标右键,选择“共享”命令,打开打印机的属性对话框,切换至“共享”选项卡,选择“共享这台打印机”,并在“共享名”输入框中填入需要共享的名称,例如CompaqIJ,单击“确定”按钮即可完成共享的设定。
提示:如果希望局域网内其他版本的操作系统在共享主机打印机时不再需要费力地查找驱动程序,我们可以在主机上预先将这些不同版本选择操作系统对应的驱动程序安装好,只要单击“其他驱动程序”按钮,选择相应的操作系统版本,单击“确定”后即可进行安装了。
2配置网络协议
为了让打印机的共享能够顺畅,我们必须在主机和客户机上都安装“文件和打印机的共享协议”。
右击桌面上的“网上邻居”,选择“属性”命令,进入到“网络连接”文件夹,在“本地连接”图标上点击鼠标右键,选择“属性”命令,如果在“常规”选项卡的“此连接使用下列项目”列表中没有找到“Microsoft网络的文件和打印机共享”,则需要单击“安装”按钮,在弹出的对话框中选择“服务”,然后点击“添加”,在“选择网络服务”窗口中选择“文件和打印机共享”,最后单击“确定”按钮即可完成。
3客户机的安装与配置
现在,主机上的工作我们已经全部完成,下面就要对需要共享打印机的客户机进行配置了。我们假设客户机也是Windows XP操作系统。在网络中每台想使用共享打印机的电脑都必须安装打印驱动程序。
第一步:单击“开始→设置→打印机和传真”,启动“添加打印机向导”,选择“网络打印机”选项。
第二步:在“指定打印机”页面中提供了几种添加网络打印机的方式。如果你不知道网络打印机的具体路径,则可以选择“浏览打印机”选择来查找局域网同一工作组内共享的打印机,已经安装了打印机的电脑,再选择打印机后点击“确定”按钮;如果已经知道了打印机的网络路径,则可以使用访问网络资源的“通用命名规范”(UNC)格式输入共享打印机的网络路径,例如“\\james\compaqIJ”(james是主机的用户名),最后点击“下一步”。
第三步:这时系统将要你再次输入打印机名,输完后,单击“下一步”按钮,接着按“完成”按钮,如果主机设置了共享密码,这里就要求输入密码。最后我们可以看到在客户机的“打印机和传真”文件夹内已经出现了共享打印机的图标,到这儿我们的网络打印机就已经安装完成了。
4让打印机更安全
如果仅仅到此为止的话,局域网内的非法用户也有可能趁机使用共享打印机,从而造成打印成本的“节节攀升”。为了阻止非法用户对打印机随意进行共享,我们有必要通过设置账号使用权限来对打印机的使用对象进行限制。通过对安装在主机上的打印机进行安全属性设置,指定只有合法账号才能使用共享打印机。
第一步:在主机的“打印机和传真”文件夹中,用鼠标右键单击其中的共享打印机图标,从右键菜单中选择“属性”选项,在接着打开的共享打印机属性设置框中,切换“安全”选项卡。
第二步:在其后打开的选项设置页面中,将“名称”列表处的“everyone”选中,并将对应“权限”列表处的“打印”选择为“拒绝”,这样任何用户都不能随意访问共享打印机了。
第三步:接着再单击“添加”按钮,将可以使用共享打印机的合法账号导入到“名称”列表中,再将导入的合法账号选中,并将对应的打印权限选择为“允许”即可。
重复第三步即可将其他需要使用共享打印机的合法账号全部导入进来,并依次将它们的打印权限设置为“允许”,最后再单击“确定”按钮即可。
提示:如果找不到“安全”选项卡,可以通过在文件夹菜单栏上依次选择“工具→文件夹选项→查看”,取消“使用简单文件共享”即可。
峡谷之巅这个区终于开服了,一时间各个大区的高端排位估计排队等候时间都多了几倍,为什么呢?大家都去峡谷之巅了啊,在这个区你不仅能遇到各大主播,还有机会狙击到我们LPL战队的选手哦,来自所有大区的高端玩家汇聚一堂,打的差就是技不如人失误多,再也没有什么借口什么菜鸡互啄,毕竟随便一个人拎出来都是各个服务器的顶尖玩家。
一些主播们首当其冲,立刻就去体验了峡谷之巅,我们熟悉的LPL解说至幻就给大家带来了第一手王者之巅的情报,六把全胜节奏非常好,队友是可以沟通的类型而且都很厉害,自己的努力可以得到回报,同样,也希望大家爱护这片净土。
不仅晒了战绩,还发了一张截图,他们寒冰和辅助卡掉了没换人,队友要求他出去三分钟我们remark 他居然就这么答应了,峡谷之巅大区素质也是峡谷之巅。
怎么说呢,能拿到这个区资格的玩家都是经过了层层考验的,想玩好一场游戏不仅要有高超的技术,还要有和队友的合作精神以及面对劣势心态不崩的抗压能力,只有这样的玩家才能真正的站在峡谷之巅,一览众山小。这样一个拥有高质量玩家的区自然可以让人有如沐春风的感觉。毕竟,丢几分是小,享受竞技游戏的乐趣才是最大的。
不仅主播们感受到了来自峡谷之巅的友好,很多玩家在这里也学到了更多
还有的玩家甚至会做记录,毕竟这里汇聚了所有大区的高端玩家,山外有山人外有人,当你走出自己的一方天地,你会发现更广阔的世界,同样,你也能学到更多的东西。
还有真正的信仰粉,在峡谷之巅里有无尽的可能,只要有实力肯努力,面对着这么多的优秀队友,你也许真的可以实现自己的梦想,甚至成为一名职业选手。
也有感受到不同服务器水平差异的玩家,以往大家都站在自己服务器最顶层,如今突然来到了高手如云的服务器,不管你之前是王者还是大师,大家都在同一起跑线,胜者为王。如果说曾经的一区艾欧尼亚代表了英雄联盟国服的最高战力,那么现在大家同一起点,不管你曾经是怎样,在峡谷之巅用实力说话。(当然,为了别的玩家们的游戏体验,我们是不建议把账号借给别人玩的哦)
当然,有人欢喜有人愁,很多玩家表示了
所以,青铜玩家的山间小道应该叫峡谷之渊?
当然,调侃也出来了,IG打野在今天的比赛中被石头人打死了,曾经大家都说一区的野怪都比别的区厉害,这回这个石头人,怕不是峡谷之巅的石头人?
总之,作为目前英雄联盟的最高战力所在,峡谷之巅这个区还是很有权威性的,不管怎么样,拿到门票就间接的证明了自己的实力,在开服的时候努力冲分,回自己区带带妹子,和基友开开黑,出去聚会聊起来一句我最近在峡谷之巅玩,倍儿有面子有没有?
①你得确认你之前所需要共享的打印机,确定在服务端已经成功设置了共享打印机。
②用户权限是否未打开。
③而其服务端的电脑系统也关闭了防火墙功能。
④服务端的电脑系统是否设置了网络用户禁止访问的权限。
⑤不在同一工作组。
:
局域网(Local Area Network,LAN)是指在某一区域内由多台计算机互联成的计算机组。一般是方圆几千米以内。局域网可以实现文件管理、应用软件共享、打印机共享、工作组内的日程安排、电子邮件和传真通信服务等功能。局域网是封闭型的,可以由办公室内的两台计算机组成,也可以由一个公司内的上千台计算机组成。
局域网(Local Area Network,LAN)是在一个局部的地理范围内(如一个学校、工厂和机关内),一般是方圆几千米以内,将各种计算机,外部设备和数据库等互相联接起来组成的计算机通信网。它可以通过数据通信网或专用数据电路,与远方的局域网、数据库或处理中心相连接,构成一个较大范围的信息处理系统。
局域网可以实现文件管理、应用软件共享、打印机共享、扫描仪共享、工作组内的日程安排、电子邮件和传真通信服务等功能。局域网严格意义上是封闭型的。它可以由办公室内几台甚至上千上万台计算机组成。决定局域网的主要技术要素为:网络拓扑,传输介质与介质访问控制方法。
局域网由网络硬件(包括网络服务器、网络工作站、网络打印机、网卡、网络互联设备等)和网络传输介质,以及网络软件所组成。
参考资料:
1 Android 应用
如果你还在寻找 Java 在哪运用,你不用东奔西走的寻找,你的身边就是。打开的 Android 手机,随便打开一个 App 应用,他们就是完全的用 Java 语言,从 Google 上搜索 Android 的 API 文档,你就会发现它和 Java 的 JDK 文档惊人的相似。从两年前的 Android 刚刚起步,到今天许多的 Android 应用都是 Java 程序员开发者开发。虽然 Android 运用了不同的 JVM 以及不同的封装方式(这可以参考原先的文章 how Android app works ),但是代码还是用 Java 语言所编写。
2 在金融业应用的服务器程序
Java 在金融服务业的应用非常广泛,许多跨国投资银行例如:Goldman Sachs(高盛投资),Citigroup(花旗集团),Barclays(巴克莱银行),Standard Charted(标准渣打银行)以及其他银行,都用 Java 来编写前台和后台的电子交易系统,结算和确认系统,数据处理项目以及其他项目。大多数情况下,Java 被用在服务器端开发,但多数没有任何前端,它们通常是从一个服务器(上一级)接收数据,处理后发向另一个处理系统(下一级处理)。Java Swing 技术旨在开发可视化界面客户端供交易者使用,但是随着近几年 C# 的崛起使程序员在客户端开发时舍弃了繁琐的代码,C# 正慢慢取代 Swing 成为可视化开发的主流。
3 网站
同样,Java 在电子商务领域以及网站开发领域占据这大部分席位。你可以运用许多不同的框架来创建 web 项目,SpringMVC,Struts20 以及 frameworks。即使是简单的 servlet,jsp 和以 struts 为基础的网站在政府项目中也是很受欢迎的。例如医疗救护,保险,教育,国防以及其他的不同部门网站都是以 Java 为基础来开发的。
4 软件工具
许多常用的软件和开发工具都是运用 Java 来编写和开发的。比如 Eclipse,IneteliJIdea 和 Netbans IDE。我认为他们去都是用 Java 来编写的。就如上面所说,Swing 曾经在可视化桌面客户端开发非常流行,它们大多数应用与金融服务领域以及投资银行,JavaFx 虽说已经得到流行,但是依然无法取代 Swing。现在 C# 已经几乎取代了 Swing 在金融开发领域的地位。
5 交易系统
第三方交易系统,现已是金融服务产业的一个很大的部分,它们同样也是 Java 编写。例如受欢迎的交易平台 Murex ,它也是 Java 编写,并与许多的银行前台所连接,提供服务。
6 J2ME 系统
随着近几年 IOS 和 Android 的出现,几乎占据了 J2ME 市场,但仍然有低端诺基亚、三星手机使用 J2ME。这个时代的大多数手机游戏,手机应用都采用 J2ME 的一部分 MIDP 和 CLDC 编写,以适应 Android 系统。但是 J2ME 依然在蓝光,磁卡,机顶盒这些产品中流行。通信应用之所以这么火是因为 Nokia 的手机依旧支持 J2ME。
7 嵌入式领域
Java 在嵌入式领域发展空间很大。在这个平台上,你只需 130KB 就能够使用 Java 技术(在智能卡或者传感器上)。最初,Java 被设计用来在嵌入书设备上工作。事实上,这只是其中的一个领域,这只是当初的“一次写入,随便畅游”的项目,现在看起来是这样了。
8 大数据技术
Hadoop 以及其他大数据处理技术都是用 Java 或者其他,例如 Apache 的基于 Java 的 HBase 和 Accumulo 以及 ElasticSearchas。但是 Java 在此领域并未占太大空间,如 MongoDB 就是在 C++ 技术基础上编写的。总的来说,只要 Hadoop 和 ElasticSearchas 能够成长壮大,Java 依旧还有潜力去在这个市场占据一部分。
9 高频交易的空间
Java 平台大幅度提高了这个平台的特性和即使编译,他同时也能够像 C++ 一样传递数据。正是由于这个原因,Java 成为的程序员编写交易平台的语言,因为虽然性能不比母语,但你可以避开它的安全性,可移植性和可维护性,以更快的速度运行,一个没有经验的 C++ 程序员会使应用程序变的更加缓慢和不可靠。
10 科学应用
今天,Java 依然是在科学应用中最好选择,包括自然语言处理。最主要的原因是因为 Java 比 C++ 或者其他语言相对其安全性、便携性、可维护性以及其他高级语言的并发性更好。
1990 年,Java 因为其 Applet 在 Internet 上相当庞大,但是随着这几年的下来,Applet 失去了其光环,最主要原因是因为各种各样的安全问题在 Applet 上出现。今天我们电脑上已经不存在桌面 Java 和 Applet。但 Java 任然是默认的软件行业的应用程序开发语言,在金融服务行业的大量使用,投资银行和电子商务应用的空间,任何一个学习 Java 的学者都有着光明的未来。Java 8 只是加强了信念,Java 将持续多年来控制软件的发展空间。
内网是自己搭建的邮件服务器么?我以前用过apache的开源邮件服务器james,也是只需要设置propssetProperty("mailhost", "smtpmymailcom");就可以了,至于smtpmymailcom是可以配置在邮件服务器里面的,跟ip没关系的
0条评论