refactor, 重构
refactor, 重构 重构是克服演进式设计中大杂烩问题的主力,通过在单独的类及方法级别上做一系列小步重构来完成。 在解决现实问题时,我们会将问题映射到脑海中的概念模型,在模型中解决问题,再将解决方案转换为实际的代码。上述问题在于我们解决了设计到代码之间的重构,但提炼出来的设计模型,并不具有实际的业务含义,这就导致在开发新需求时,其他同学并不能很自然地将业务问题映射到该设计模型。设计似乎变成了重构者的自娱自乐,代码继续腐败,重新重构……无休止的循环。
refactor, 重构 重构是克服演进式设计中大杂烩问题的主力,通过在单独的类及方法级别上做一系列小步重构来完成。 在解决现实问题时,我们会将问题映射到脑海中的概念模型,在模型中解决问题,再将解决方案转换为实际的代码。上述问题在于我们解决了设计到代码之间的重构,但提炼出来的设计模型,并不具有实际的业务含义,这就导致在开发新需求时,其他同学并不能很自然地将业务问题映射到该设计模型。设计似乎变成了重构者的自娱自乐,代码继续腐败,重新重构……无休止的循环。
Python Hello World install python3 pip3 sudo dnf install python3 http://blog.csdn.net/pjeby/article/details/1212592 简介 我们将看一下如何用Python编写运行一个传统的"Hello World"程序。通过它,你将学会如何编写、保存和运行Python程序。 有两种使用Python运行你的程序的方式——使用交互式的带提示符的解释器或使用源文件。我们将学习这两种方法。 使用带提示符的解释器 在命令行的shell提示符下键入python,启动解释器。现在输入print 'Hello World',然后按Enter键。你应该可以看到输出的单词Hello World。 对于Windows用户,只要你正确的设置了PATH变量,你应该可以从命令行启动解释器。或者你可以选择使用IDLE程序。IDLE是集成开发环境的缩写。点击开始->程序->Python 2.3->IDLE(Python GUI)。Linux用户也可以使用IDLE。 注意,>>>是你键入Python语句的提示符。 例1 使用带提示符的Python解释器 $ python Python 2.4.3 (#1, Jul 26 2006, 16:42:40) [GCC 3.4.2 20050110 (Red Hat 3.4.2-6.fc3)] on linux2 Type “help”, “copyright”, “credits” or “license” for more information. print ‘hello world’ hello world 注意,Python会在下一行立即给出你输出!你刚才键入的是一句Python 语句 。我们使用print (不要惊讶) 来打印你提供给它的值。这里,我们提供的是文本Hello World,它被迅速地打印在屏幕上。 如何退出Python提示符: 如果你使用的是Linux/BSD shell,那么按Ctrl-d退出提示符。如果是在Windows命令行中,则按Ctrl-z再按Enter。 挑选一个编辑器 在我们开始讲述以源文件方式编写Python程序之前,我们需要一个编辑器来写源文件。挑选一个编辑器确实是极其重要的。你挑选一个编辑器就如同你挑选一辆你将购买的轿车一样。一个好的编辑器会帮助你方便地编写Python程序,使你地编程旅程更加舒适,帮助你更加快捷安全地到达目的地 (实现目标) 。 ...
Markdown 语法 JetBrain Writerside implements the CommonMark Spec: https://spec.commonmark.org/0.30/ 转义 比如在 Markdown 中显示反引号, 可以用反斜杠转义 ` 字体 加粗 要加粗的文字左右分别用两个*号包起来 斜体 要倾斜的文字左右分别用一个*号包起来 *foo* foobarfoo 斜体加粗 要倾斜和加粗的文字左右分别用三个*号包起来 删除线 要加删除线的文字左右分别用两个~~号包起来 示例 这是加粗的文字 这是倾斜的文字 这是斜体加粗的文字 这是加删除线的文字 标题 # 一级标题 ## 二级标题 ### 三级标题 #### 四级标题 ##### 五级标题 ###### 六级标题 图片  # 本地图片  # 网络图片   表格 | t0 | t1 | | - | - | | c0r0 | c1r0| | c1r1 | c1r1 | 引用 >foo Markdown 是一种轻量级的标记语言,由John Gruber和Aaron Swartz创建,使其成为可读性最大并可再发行的可输入输出的格式。这种语言创建灵感来自于已经存在的带标记的电子邮件文本。Markdown 允许 HTML 语法,所以使用者如果需要可以直接用 HTML来表示是可以的。Markdown最初由Gruber应用在Perl语言中,但现在已经有多种编程语言应用了。它是开源项目,并以BSD-style许可证的许可方式以插件形式或内容管理系统形式发布。 ...
Spring中bean的作用域 http://blog.csdn.net/ProvidenceZY/article/details/1878582 如何使用spring的作用域: <bean id="role" class="spring.chapter2.maryGame.Role" scope="singleton"/> 这里的scope就是用来配置spring bean的作用域,它标识bean的作用域。 在spring2.0之前bean只有2种作用域即: singleton(单例)、non-singleton (也称prototype) , Spring2.0以后,增加了session、request、global session三种专用于Web应用程序上下文的Bean。因此,默认情况下Spring2.0现在有五种类型的Bean。当然,Spring2.0对Bean的类型的设计进行了重构,并设计出灵活的Bean类型支持,理论上可以有无数多种类型的Bean,用户可以根据自己的需要,增加新的Bean类型,满足实际应用需求。 1、singleton作用域 当一个bean的作用域设置为singleton, 那么Spring IOC容器中只会存在一个共享的bean实例,并且所有对bean的请求,只要id与该bean定义相匹配,则只会返回bean的同一实例。换言之,当把一个bean定义设置为singleton作用域时,Spring IOC容器只会创建该bean定义的唯一实例。这个单一实例会被存储到单例缓存 (singleton cache) 中,并且所有针对该bean的后续请求和引用都将返回被缓存的对象实例,这里要注意的是singleton作用域和GOF设计模式中的单例是完全不同的,单例设计模式表示一个ClassLoader中只有一个class存在,而这里的singleton则表示一个容器对应一个bean,也就是说当一个bean被标识为singleton时候,spring的IOC容器中只会存在一个该bean。 配置实例: <bean id="role" class="spring.chapter2.maryGame.Role" scope="singleton"/> 或者 <bean id="role" class="spring.chapter2.maryGame.Role" singleton="true"/> 2、prototype prototype作用域部署的bean,每一次请求 (将其注入到另一个bean中,或者以程序的方式调用容器的getBean()方法) 都会产生一个新的bean实例,相当与一个new的操作,对于prototype作用域的bean,有一点非常重要,那就是Spring不能对一个prototype bean的整个生命周期负责,容器在初始化、配置、装饰或者是装配完一个prototype实例后,将它交给客户端,随后就对该prototype实例不闻不问了。不管何种作用域,容器都会调用所有对象的初始化生命周期回调方法,而对prototype而言,任何配置好的析构生命周期回调方法都将不会被调用。清除prototype作用域的对象并释放任何prototype bean所持有的昂贵资源,都是客户端代码的职责。 (让Spring容器释放被singleton作用域bean占用资源的一种可行方式是,通过使用bean的后置处理器,该处理器持有要被清除的bean的引用。) 配置实例: <bean id="role" class="spring.chapter2.maryGame.Role" scope="prototype"/> 或者 <beanid="role" class="spring.chapter2.maryGame.Role" singleton="false"/> 3、request request表示该针对每一次HTTP请求都会产生一个新的bean,同时该bean仅在当前HTTP request内有效,配置实例: request、session、global session使用的时候首先要在初始化web的web.xml中做如下配置: 如果你使用的是Servlet 2.4及以上的web容器,那么你仅需要在web应用的XML声明文件web.xml中增加下述ContextListener即可: <web-app> … org.springframework.web.context.request.RequestContextListener … ...
开源许可证, Open Source License, BSD, MIT, Apache,GPL 开源许可证(Open Source License) 由宽松到严紧排序,常用的开源许可证有: MIT BSD Apache LGPL GPL MIT、BSD 许可证都源自大学,体现了简单、开放和包容的特点。 MIT、BSD、Apache 三者都支持闭源的后续开发。 GPL、LGPL 传染性开源,编译的代码里用了这里的代码,都必须开源。 MIT 分发软件时,必须保留原始的许可证声明,与 BSD (二条款版) 基本一致。 https://opensource.org/licenses/mit-license.php 来源于大学,MIT 许可证是史上最为简洁和慷慨(permissive)的开源协议之一。作者只想保留版权, 而无任何其他了限制. 也就是说, 你必须在你的发行版里包含原许可协议的声明, 无论你是以二进制发布的还是以源代码发布的。 简言之: 用户可以拿你的代码做任何想做的事情 用户在项目副本中要包含版权声明和许可声明 你无需承担任何责任 应用案例有:JQuery、Rails 等 BSD (二条款版) 分发软件时,必须保留原始的许可证声明。 来源于大学,BSD可证与MIT差不多,也非常简单、慷慨。 BSD开源协议是一个给于使用者很大自由的协议。基本上使用者可以”为所欲为”,可以自由的使用,修改源代码,也可以将修改后的代码作为开源或者专有软件再发布。 但”为所欲为”的前提当你发布使用了BSD协议的代码,或则以BSD协议代码为基础做二次开发自己的产品时,需要满足三个条件: 如果再发布的产品中包含源代码,则在源代码中必须带有原来代码中的BSD协议。 如果再发布的只是二进制类库/软件,则需要在类库/软件的文档和版权声明中包含原来代码中的BSD协议。 不可以用开源代码的作者/机构名字和原来产品的名字做市场推广。 BSD 代码鼓励代码共享,但需要尊重代码作者的著作权。BSD由于允许使用者修改和重新发布代码,也允许使用或在BSD代码上开发商业软件发布和销售,因此是对 商业集成很友好的协议。而很多的公司企业在选用开源产品的时候都首选BSD协议,因为可以完全控制这些第三方的代码,在必要的时候可以修改或者二次开发。 BSD (三条款版) 分发软件时,必须保留原始的许可证声明。不得使用原始作者的名字为软件促销。 Apache 2 分发软件时,必须保留原始的许可证声明。凡是修改过的文件,必须向用户说明该文件修改过;没有修改过的文件,必须保持许可证不变。 来自apache,类似MIT许可证,但它重视专利权。 Apache Licence是著名的非盈利开源组织Apache采用的协议。该协议和BSD类似,同样鼓励代码共享和尊重原作者的著作权,同样允许代码修改,再发布(作为开源或商业软件)。需要满足的条件也和BSD类似: 需要给代码的用户一份Apache Licence 如果你修改了代码,需要再被修改的文件中说明。 在延伸的代码中(修改和有源代码衍生的代码中)需要带有原来代码中的协议,商标,专利声明和其他原来作者规定需要包含的说明。 如果再发布的产品中包含一个Notice文件,则在Notice文件中需要带有Apache Licence。你可以在Notice中增加自己的许可,但不可以表现为对Apache Licence构成更改。 Apache Licence也是对商业应用友好的许可。使用者也可以在需要的时候修改代码来满足需要并作为开源或商业产品发布/销售。 应用案例有:Apache 家族、SVN、NuGet 等等。 ...
pacakge-info.java http://strong-life-126-com.iteye.com/blog/806246 翻看以前的笔记,看到一个特殊的java文件: pacakge-info.java,虽然有记录,但是不全,就尝试着追踪一下该问题, 分享一下流水账式的结果。 首先,它不能随便被创建。在Eclipse中, package-info文件不能随便被创建,会报"Type name is notvalid"错误,类名无效,Java变量定义规范是: 字母、数字、下划线,还有那个不怎么常用的$符号 (顺带说下,Java是支持中文名称的变量,习惯挑战的同学可以尝试下,分享一下这方面的经验) ,这个中划线可不再之列,那怎么创建这个文件呢? 很简单,用记事本创建一个,然后拷贝进去再改一下就成了,更直接的办法就是从别的项目中拷贝过来一个,这更方便。 其次,服务的对象很特殊。一个类是一类或一组事物的描述,比如Dog这个类,就是描述旺财的,那package-info这个类是描述啥的呢?它总要有一个被描述或被陈述的对象,它是描述和记录本包信息。 最后,类不能带有public、private访问权限。package-info.java再怎么特殊,也是一个类文件,也会被编译成package-info.class,但是在package-info.java中只能声明默认访问权限的类,也就是友好类。 其实还有几个特殊的地方,比如不可以继承,没有接口,没有类间关系 (关联、组合、聚合等等) 等。 这个文件的特殊性说完了,那再说说它有什么作用,它有三个作用: 为标注在包上Annotation提供便利; 声明友好类和包常量; 提供包的整体注释说明。 我们来建立一个项目演示这三个作用,建立一个package-info的Java Project,在com.company包三个类:package-info.java 是我们重点关注的,PkgAnnotation.java是一个标注在包上的注解定义,Client.java模拟业务操作类。其结构如下图: 为标注在包上Annotation提供便利 首先定义一个包类型的注解,它只能放置的一个包上: Java代码 /** 定义只能标注在package上的注解 */ @Target(ElementType.PACKAGE) @Retention(RetentionPolicy.RUNTIME) public @interface PkgAnnotation { } 再定义一个package-info类,这个是一个特殊的类,先看代码: Java代码 @PkgAnnotation package com.company; 很简单,就这么个文件,里面啥都没有,就这两句话,没有class类,没有常变量声明。接着写一个模拟交易类,代码如下: Java代码 public class Client { public static void main(String[] args) { //可以通过I/O操作或配置项获得包名 String pkgName = “com.company”; Package pkg = Package.getPackage(pkgName); //获得包上的注解 Annotation[] annotations = pkg.getAnnotations(); //遍历注解数组 for(Annotation an:annotations){ if(an instanceof PkgAnnotation){ ...
CSRF/XSRF CSRF (Cross-site request forgery跨站请求伪造,也被称成为"one click attack"或者session riding,通常缩写为CSRF或者XSRF,是一种对网站的恶意利用。尽管听起来像跨站脚本 (XSS) ,但它与XSS非常不同,并且攻击方式几乎相左。XSS利用站点内的信任用户,而CSRF则通过伪装来自受信任用户的请求来利用受信任的网站。与XSS攻击相比,CSRF攻击往往不大流行 (因此对其进行防范的资源也相当稀少) 和难以防范,所以被认为比XSS更具危险性。攻击通过在授权用户访问的页面中包含链接或者脚本的方式工作。例如: 一个网站用户Bob可能正在浏览聊天论坛,而同时另一个用户Alice也在此论坛中,并且后者刚刚发布了一个具有Bob银行链接的图片消息。设想一下,Alice编写了一个在Bob的银行站点上进行取款的form提交的链接,并将此链接作为图片tag。如果Bob的银行在cookie中保存他的授权信息,并且此cookie没有过期,那么当Bob的浏览器尝试装载图片时将提交这个取款form和他的cookie,这样在没经Bob同意的情况下便授权了这次事务。 CSRF是一种依赖web浏览器的、被混淆过的代理人攻击 (deputy attack) 。在上面银行示例中的代理人是Bob的web浏览器,它被混淆后误将Bob的授权直接交给了Alice使用。 下面是CSRF的常见特性: 依靠用户标识危害网站 利用网站对用户标识的信任 欺骗用户的浏览器发送HTTP请求给目标站点 另外可以通过IMG标签会触发一个GET请求,可以利用它来实现CSRF攻击。风险在于那些通过基于受信任的输入form和对特定行为无需授权的已认证的用户来执行某些行为的web应用。已经通过被保存在用户浏览器中的cookie进行认证的用户将在完全无知的情况下发送HTTP请求到那个信任他的站点,进而进行用户不愿做的行为。 使用图片的CSRF攻击常常出现在网络论坛中,因为那里允许用户发布图片而不能使用JavaScript。贴图只是GET的方式,很多时候我们需要伪造POST的请求。一个办法是利用跨站,当然目标站点可能不存在跨站,这个时候我们可以从第三方网站发动攻击。 比如我要攻击一个存在问题的blog,那就先去目标blog留言,留下一个网址,诱其主人点击过来 (这个就要看你的忽悠本事咯:p) ,然后构造个HTML表单提交些数据过去。 多窗口浏览器就帮了一点忙。 多窗口浏览器 (firefox、遨游、MyIE……) 便捷的同时也带来了一些问题,因为多窗口浏览器新开的窗口是具有当前所有会话的。即我用IE登陆了我的Blog,然后我想看新闻了,又运行一个IE进程,这个时候两个IE窗口的会话是彼此独立的,从看新闻的IE发送请求到Blog不会有我登录的cookie;但是多窗口浏览器永远都只有一个进程,各窗口的会话是通用的,即看新闻的窗口发请求到Blog是会带上我在blog登录的cookie。 想一想,当我们用鼠标在Blog/BBS/WebMail点击别人留下的链接的时候,说不定一场精心准备的CSRF攻击正等着我们。
元胞自动机,Cellular Automaton http://baike.baidu.com/view/389880.htm 元胞自动机(Cellular Automaton,复数为Cellular Automata,简称CA,也有人译为细胞自动机、点格自动机、分子自动机或单元自动机)。是一时间和空间都离散的动力系统。散布在规则格网 (Lattice Grid)中的每一元胞(Cell)取有限的离散状态,遵循同样的作用规则,依据确定的局部规则作同步更新。大量元胞通过简单的相互作用而构成动态系统的演化。 不同于一般的动力学模型,元胞自动机不是由严格定义的物理方程或函数确定,而是用一系列模型构造的规则构成。凡是满足这些规则的模型都可以算作是元胞自动机模型。因此,元胞自动机是一类模型的总称,或者说是一个方法框架。其特点是时间、空间、状态都离散,每个变量只取有限多个状态,且其状态改变的规则在时间和空间上都是局部的。 具体解释 元胞自动机的构建没有固定的数学公式,构成方式繁杂,变种很多,行为复杂。故其分类难度也较大,自元胞自动机产生以来,对于元胞自动机分类的研究就是元胞自动机的一个重要的研究课题和核心理论,在基于不同的出发点,元胞自动机可有多种分类,其中,最具影响力的当属S. Wolfram在80年代初做的基于动力学行为的元胞自动机分类,而基于维数的元胞自动机分类也是最简单和最常用的划分。除此之外,在1990年,Howard A.Gutowitz提出了基于元胞自动机行为的马尔科夫概率量测的层次化、参量化的分类体系 (Gutowitz,H. A.,1990) 。下面就上述的前两种分类作进一步的介绍。同时就几种特殊类型的元胞自动机进行介绍和探讨S. Wolfrarm在详细分析研究了一维元胞自动机的演化行为,并在大量的计算机实验的基础上,将所有元胞自动机的动力学行为归纳为四大类 (Wolfram. S.,1986): ⑴平稳型:自任何初始状态开始,经过一定时间运行后,元胞空间趋于一个空间平稳的构形,这里空间平稳即指每一个元胞处于固定状态。不随时间变化而变化。 ⑵周期型: 经过一定时间运行后,元胞空间趋于一系列简单的固定结构 (Stable Patterns) 或周期结构 (Perlodical Patterns)。由于这些结构可看作是一种滤波器 (Filter) ,故可应用到图像处理的研究中。 ⑶混沌型: 自任何初始状态开始,经过一定时间运行后,元胞自动机表现出混沌的非周期行为,所生成的结构的统计特征不再变止,通常表现为分形分维特征。 ⑷复杂型: 出现复杂的局部结构,或者说是局部的混沌,其中有些会不断地传播。 分别描述 从另一角度,元胞自动机可视为动力系统,因而可将初试点、轨道、不动点、周期轨和终极轨等一系列概念用到元胞自动机的研究中,上述分类,又可以分别描述为 (谭跃进,1996;谢惠民,1994;李才伟、1997) ; ⑴均匀状态,即点态吸引子,或称不动点; ⑵简单的周期结构,即周期性吸引子,或称周期轨; ⑶混沌的非周期性模式,即混沌吸引子; ⑷这第四类行为可以与生命系统等复杂系统中的自组织现象相比拟,但在连续系统中没有相对应的模式。但从研究元胞自动机的角度讲,最具研究价值的具有第四类行为的元胞自动机,因为这类元胞自动机被认为具有"突现计算"(Emergent Computation) 功能,研究表明,可以用作广义计算机 (Universal Computer) 以仿真任意复杂的计算过程。另外,此类元胞自动机在发展过程中还表现出很强的不可逆 (lrreversibility) 特征,而且,这种元胞自动机在若干有限循环后,有可能会 “死"掉,即所有元胞的状态变为零。 应用 元胞自动机可用来研究很多一般现象。其中包括通信、信息传递 (Communicahon) 、计算 (Compulation) 、构造 (ConsTruction) 、生长 (Growth) 、复制 (Reproductionj、竞争 (Competition) 与进化 (Evolutio,]) 等 (Smith A.,1969;Perrier,J.Y.,1996) 。同时。它为动力学系统理论中有关秩序 (Ordering) 、紊动 (Turbulence) 、混沌 (Chaos) 、非对称 (Symmetry-Breaking) 、分形 (Fractality) 等系统整体行为与复杂现象的研究提供了一个有效的模型工具 (Vichhac。G,1984; Bennett,C,1985) 。 ...
分布式消息队列 分布式消息队列是是大型分布式系统不可缺少的中间件,主要解决应用耦合、异步消息、流量削锋等问题。实现高性能、高可用、可伸缩和最终一致性架构。 对于一个架构师来说,在大型系统设计中,会经常需要面对同步和异步等架构问题,搞明白这些问题,能更好地实现程序并行执行,减少等待或无效操作,以及充分利用计算机的性能! 本文将详细讲解: 1.同步架构和异步架构的区别 2.异步架构的主要组成部分: 消息生产者、消息消费者、分布式消息队列 3.异步架构的两种主要模型: 点对点模型和发布订阅模型。 4.消息队列的好处 5.消息队列相关产品 建议用10min通读,搞懂分布式消息队列的核心内容。 一、同步架构和异步架构的区别 1.同步调用 是指从请求的发起一直到最终的处理完成期间,请求的调用方一直在同步阻塞等待调用的处理完成。 图片描述 如图,在这个例子中客户端代码ClientCode,需要执行发送邮件sendEmail这样一个操作,它会调用EmailService进行发送,而EmailService会调用SmtpEmailAdapter这样一个类来进行处理,而这个类会调用远程的一个服务,通过SMTP和TCP协议把请求发送给它。 而远程服务器收到消息以后会对消息进行一系列的操作,然后将邮件发送出去,再进行返回。Adapter收到返回后,再返回给EmailService,EmailService收到返回后再把返回结果返回给Clientcode。 图片描述 ClientCode在sendEmail发出请求后,就一直都阻塞在这里,等待最终调用结果的返回,是成功还是失败。因为这个过程是阻塞等待的,所以这个过程也就是同步调用。 2.异步调用 是指在请求发起的处理过程中,客户端的代码已经返回了,它可以继续进行自己的后续操作,而不需要等待调用处理完成,这就叫做异步调用。 图片描述 异步调用过程,同样看刚刚发送邮件的例子,用户Clientcode调用EmailService以后,EmailService会把这个调用请求发送给消息队列,然后就立即返回了。Clientcode收到返回以后继续向下处理,不会继续阻塞等待。实际上消息发送到Queue后,还没有被处理,我们看到后面的消息消费,其实要比EmailService返回可能还要晚一点,EmailService返回以后消息才会被消费处理。 有一个QueueConsumer消息队列的消费者,从消息队列中取出这个消息,再把这个消息发送给SmtpAdapter,也就是调用SmtpAdapter,处理逻辑跟同步调用一样,SmtpAdapter通过SMTP的通讯协议,把消息发送给远程的一个服务器,进行邮件发送,通过RemoteServer进行处理,处理完了收到返回,再把返回结果通知消息队列Queue。 在这个过程中,客户端的调用,也就是应用程序的调用,和业务逻辑真正发送邮件的操作是不同步的。 二、异步架构的主要组成部分 使用异步调用架构的主要手段,就是通过消息队列构建 消息的生产者将消息发送到消息队列以后,由消息的消费者从消息队列中获取消息,然后进行业务逻辑的处理,消息的生产者和消费者是异步处理的,彼此不会等待阻塞,所以叫做异步架构。 使用消息队列构建一个异步调用架构,你需要了解如下3种角色。 1.消息的生产者 是客户端应用程序代码的一部分,用来初始化异步调用处理流程。在基于消息队列的处理中,生产者的职责非常少,它要做的就是创建一个合法的消息,并把这个消息发送到消息队列中,由应用开发者决定生产者的代码在哪里执行,什么时候发送消息。 2.消息队列 消息队列是消息发送的目的地和发给消费者的一个缓冲。消息队列实现的方法有好多种,可以用共享文件夹,也可以用关系数据库或者NoSQL系统,当然最主要的还是使用专门的分布式消息队列服务器来实现。 3.消息的消费者 消息的消费者从消息队列中接受并处理消息,消息的消费者也是由应用开发者实现的,但是它是一个异步处理的组件。消息的消费者不需要知道生产者存在,它只依赖消息队列中的消息。消息的消费者通常部署在独立的服务器上,和消息的生产者完全隔离,并且可以通过添加硬件的方式进行伸缩。 三、异步架构的两种主要模型 使用消息队列构建异步的调用架构,你还需要知道两种模型: 点对点模型和发布订阅模型。 1.点对点模型 消费者和生产者只需要知道消息队列的名字,生产者发送消息到消息队列中,而消息队列的另一端是多个消费者竞争消费消息,每个到达消息队列的消息只会被路由到一个消费者中去,所以消费者看到的是全部消息的一个子集。我们看这张图,消息的生产者有多个,消息的消费者也有多个,多个生产者将消息发送到消息队列中,而有多个消费者去消息队列中对消息进行竞争性的消费。每个消息只会被一个消费者消费,每个消费者只会消费消息队列中的一部分消息。 2.发布订阅模型 在发布订阅模型中,消息可能被发送到不止一个消费者,生产者发送消息到一个主题,而不是队列中。消息被发布到主题后,就会被克隆给每一个订阅它的消费者,每个消费者接收一份消息复制到自己的私有队列。消费者可以独立于其他消费者使用自己订阅的消息,消费者之间不会竞争消息。常用的分布式消息队列都支持发布订阅模型,也就是说消息的发布订阅模型是分布式消息队列的一个功能特性。 3.两个模型的应用 点对点模型: 主要用于一些耗时较长的、逻辑相对独立的业务。 比如说我前面的讲到的发送邮件这样一个操作。因为发送邮件比较耗时,而且应用程序其实也并不太关心邮件发送是否成功,发送邮件的逻辑也相对比较独立,所以它只需要把邮件消息丢到消息队列中就可以返回了,而消费者也不需要关心是哪个生产者去发送的邮件,它只需要把邮件消息内容取出来以后进行消费,通过远程服务器将邮件发送出去就可以了。而且每个邮件只需要被发送一次。所以消息只被一个消费者消费就可以了。 发布订阅模型: 如新用户注册这样一个消息,需要使用按主题发布的方式。 比如新用户注册,一个新用户注册成功以后,需要给用户发送一封激活邮件,发送一条欢迎短信,还需要将用户注册数据写入数据库,甚至需要将新用户信息发送给关联企业的系统,比如淘宝新用户信息发送给支付宝,这样允许用户可以一次注册就能登录使用多个关联产品。一个新用户注册,会把注册消息发送给一个主题,多种消费者可以订阅这个主题。比如发送邮件的消费者、发送短信的消费者、将注册信息写入数据库的消费者,跨系统同步消息的消费者等。 四、消息队列的好处 1.实现异步处理,提升处理性能 对一些比较耗时的操作,可以把处理过程通过消息队列进行异步处理。这样做可以推迟耗时操作的处理,使耗时操作异步化,而不必阻塞客户端的程序,客户端的程序在得到处理结果之前就可以继续执行,从而提高客户端程序的处理性能。 2.可以让系统获得更好的伸缩性 耗时的任务可以通过分布式消息队列,向多台消费者服务器并行发送消息,然后在很多台消费者服务器上并行处理消息,也就是说可以在多台物理服务器上运行消费者。那么当负载上升的时候,可以很容易地添加更多的机器成为消费者。 图片描述 如图中的例子,用户上传文件后,通过发布消息的方式,通知后端的消费者获取数据、读取文件,进行异步的文件处理操作。那么当前端发布更多文件的时候,或者处理逻辑比较复杂的时候,就可以通过添加后端的消费者服务器,提供更强大的处理能力。 3.可以平衡流量峰值,削峰填谷 使用消息队列,即便是访问流量持续的增长,系统依然可以持续地接收请求。这种情况下,虽然生产者发布消息的速度比消费者消费消息的速度快,但是可以持续的将消息纳入到消息队列中,用消息队列作为消息的缓冲,因此短时间内,发布者不会受到消费处理能力的影响。 从这张图可以看到,因为消息的生产者是直接面向用户请求的,而用户的请求访问压力是不均衡的。如淘宝每天的访问高峰是在上午10点左右,而新浪微博则可能在某个明星半夜发一条微博后突然出现访问高峰。 在访问高峰,用户的并发访问数可能超过了系统的处理能力,所以在高峰期就可能会导致系统负载过大,响应速度变慢,更严重的可能会导致系统崩溃。这种情况下,通过消息队列将用户请求的消息纳入到消息队列中,通过消息队列缓冲消费者处理消息的速度。 如图中所示,消息的生产者它有高峰有低谷,但是到了消费者这里,只会按照自己的最佳处理能力去消费消息。高峰期它会把消息缓冲在消息队列中,而在低谷期它也还是使用自己最大的处理能力去获取消息,将前面缓冲起来、来不及及时处理的消息处理掉。那么,通过这种手段可以实现系统负载消峰填谷,也就是说将访问的高峰消掉,而将访问的低谷填平,使系统处在一个最佳的处理状态之下,不会对系统的负载产生太大的冲击。 4.失败隔离和自我修复 因为发布者不直接依赖消费者,所以分布式消息队列可以将消费者系统产生的错误异常与生产者系统隔离开来,生产者不受消费者失败的影响。 当在消息消费过程中出现处理逻辑失败的时候,这个错误只会影响到消费者自身,而不会传递给消息的生产者,也就是应用程序可以按照原来的处理逻辑继续执行。 所以,这也就意味着在任何时候都可以对后端的服务器执行维护和发布操作。可以重启、添加或删除服务器,而不影响生产者的可用性,这样简化了部署和服务器管理的难度。 5.可以使生产者和消费者的代码实现解耦合 也就是说可以多个生产者发布消息,多个消费者处理消息,共同完成完整的业务处理逻辑,但是它们的不需要直接的交互调用,没有代码的依赖耦合。在传统的同步调用中,调用者代码必须要依赖被调用者的代码,也就是生产者代码必须要依赖消费者的处理逻辑代码,代码需要直接的耦合,而使用消息队列,这两部分的代码不需要进行任何的耦合。 耦合程度越低的代码越容易维护,也越容易进行扩展。 比如新用户注册,如果用传统同步调用的方式,那么发邮件、发短信、写数据库、通知关联系统这些代码会和用户注册代码直接耦合起来,整个代码看起来就是完成用户注册逻辑后,后面必然跟着发邮件、发短信这些代码。如果要新增一个功能,比如将监控用户注册情况,将注册信息发送到业务监控系统,就必须要修改前面的代码,至少增加一行代码,发送注册信息到监控系统,我们知道,任何代码的修改都可能会引起bug。 ...
xml 编码 前同天和同事在讨论xml里的encoding属性和文件格式的关系,终于彻底的弄清楚了。 以前理解的是,xml里的encoding里定义必须与文件格式相匹配。即有这样的xml Introduction,那么,文件格式必须是一个utf-8文件,即文件的前两个字节要是一个utf-8头FF FE。 (后来才弄清楚,FF FE不是utf-8的BOM。。就是说我的错误理解持续了相当长一段时间。。) 下面把讨论的几个阶段大概说一下。 刚开始讨论时,我很肯定的告诉他,encoding的值必须和文件格式 (即BOM,BOM就是 byte order mark的缩写) 相匹配,不然在解析XML时,可能会出现 (比如文档含有某个UNICODE字符,而encoding或BOM指定的格式不匹配,就会出错,当时我是这样的意思) ,然后他又告诉我,好像不是这样,我用DELPHI创建的XML文件,没有BOM,XML里面有中文内容,encoding里指定的是UTF-8,用IE可以正常打开啊。 他在发现他所创建的XML文件没有BOM时,有个有趣的地方,就是用UE打开这类含有UNICODE字符的文件时,UE会自动在文件前面加上FF FE,使得文件可以正常显示,所以原本没有BOM的文件,在UE下的十六进制下浏览,会看到多了个BOM,这个功能可以在UE的OPTIONS里去掉的,想知道的可以自己去找找。 然后我有点大头了,怎么会这样呢,然后想啊想,突然他发了一条信息过来,内容如下: W3C定义了三条XML解析器如何正确读取XML文件的编码的规则: 1,如果文挡有BOM(字节顺序标记,一般来说,如果保存为unicode格式,则包含BOM,ANSI则无),就定义了文件编码 2,如果没有BOM,就查看XML声明的编码属性 3,如果上述两个都没有,就假定XML文挡采用UTF-8编码 有了这三条规则,那这个规则就清楚多了。 首先,XML解析器根据文件的BOM来解析文件;如果没找到BOM,由用XML里的encoding属性指定的编码;如果xml里encoding没指定的话,就默认用utf-8来解析文档。然后又可以推出,BOM和ENCODING都有的话,则以BOM指定的为准。 啊!突然觉得有标准文档多好!虽然是那么的理所当然。 至此,终于把xml里的encoding和文件格式的关系弄懂了。虽然这篇记录只有那几百个字内容,但是我们当时在讨论的时候,总时间差不多花了2个小时。 http://blog.csdn.net/fzy112001/article/details/4183139 http://www.cnblogs.com/azol/articles/1137035.html
XML XML即可扩展标记语言 (eXtensible Markup Language) ,是被设计用来描述、存储、传送及交换数据。XML是当前处理结构化文档信息的有力工具,标记是指计算机所能理解的信息符号 XML是什么?XML即可扩展标记语言 (eXtensible Markup Language) ,是被设计用来描述、存储、传送及交换数据。XML是当前处理结构化文档信息的有力工具,标记是指计算机所能理解的信息符号,通过此种标记,计算机之间可以处理包含各种信息的文章等。简单说,XML就是一种数据的描述语言,你可以把它理解为微型数据库,对了!它就是数据库。 作为新手的你,可能还无法理解它,没有关系,理论都是死的,不妨从应用中了解它!如果你是一个开发人员或准备成为一个开发人员,必然会有恍然大悟的一刻。 下面了解一下XML版本 1998年2月10日,XML 1.0作为一项 W3C推荐被发布。 2000年10月6日,XML 1.0(SE)作为一项 W3C 推荐被发布。第二版仅仅是在合并第一版的勘误表的基础上进行的修正 (漏洞修复) 。 2001年12月13日,XML 1.1作为一份工作草案被发布,并作为一项候选推荐发布于2002年10月15日。XML 1.1 允许在名称中使用几乎所有的 Unicode 字符。 可扩展标记语言 (Extensible Markup Language, XML) ,用于标记电子文件使其具有结构性的标记语言,可以用来标记数据、定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言。 XML是标准通用标记语言 (SGML) 的子集,非常适合 Web 传输。XML 提供统一的方法来描述和交换独立于应用程序或供应商的结构化数据。 XML与Access,Oracle和SQL Server等数据库不同,数据库提供了更强有力的数据存储和分析能力,例如: 数据索引、排序、查找、相关一致性等,XML仅仅是存储数据。事实上XML与其他数据表现形式最大的不同是: 他极其简单。这是一个看上去有点琐细的优点,但正是这点使XML与众不同。 XML与HTML的设计区别是: XML是用来存储数据的,其焦点是数据的内容。而HTML 被设计用来显示数据,其焦点是数据的外观。 XML和HTML语法区别: HTML的标记不是所有的都需要成对出现,XML则要求所有的标记必须成对出现;HTML标记不区分大小写,XML则相反。 结合 XML的简单使其易于在任何应用程序中读写数据,这使XML很快成为数据交换的唯一公共语言,虽然不同的应用软件也支持其它的数据交换格式,但不久之后他们都将支持XML,那就意味着程序可以更容易的与Windows,Mac OS,Linux以及其他平台下产生的信息结合,然后可以很容易加载XML数据到程序中并分析他,并以XML格式输出结果。 友好 为了使得SGML显得用户友好,XML重新定义了SGML的一些内部值和参数,去掉了大量的很少用到的功能,这些繁杂的功能使得SGML在设计网站时显得复杂化。XML保留了SGML的结构化功能,这样就使得网站设计者可以定义自己的文档类型,XML同时也推出一种新型文档类型,使得开发者也可以不必定义文档类型。 简明语法 SGML常用来定义针对HTML的文档类型定义 (DTD) ,同时它也常用于编写XML的DTD。SGML的问题就在于,它允许出现一些奇怪的语法,这让创建HTML的解析器成为一个大难题: 1 某些起始标签不允许出现结束标签,例如HTML中<img>标签。包含了结束标签就会出现错误。 2 某些起始标签可以选择性出现结束标签或者隐含了结束标签。 3 某些起始标签要求必须出现结束标签,例如HTML中<script>标签。 4 标签可以以任何顺序嵌套。即使结束标签不按照起始标签的逆序出现也是允许的,例如,This is a sample string是正确的。 5 某些特性要求必须包含值,例如<img src="picture.jpg">中的src特性。 6 某些特性不要求一定有值,例如中的nowrap特性。 7 定义特性的两边有没有加上双引号都是可以的,所以<img src="picture.jpg">和<img src=picture.jpg>都是允许的。 这些问题使建立一个SGML语言的解析器变成了一项艰巨的任务。判断何时应用以上规则的困难导致了SGML语言的定义一直停滞不前。以这些问题作为出发点,XML逐渐步入我们的视野。 XML去掉了之前令许多开发人员头疼的SGML的随意语法。在XML中,采用了如下的语法: 1 任何的起始标签都必须有一个结束标签。 2 可以采用另一种简化语法,可以在一个标签中同时表示起始和结束标签。这种语法是在大于符号之前紧跟一个斜线 (/) ,例如<tag/ >。XML解析器会将其翻译成<tag></tag>。 3 标签必须按合适的顺序进行嵌套,所以结束标签必须按镜像顺序匹配起始标签,例如this is a samplestring。这好比是将起始和结束标签看作是数学中的左右括号: 在没有关闭所有的内部括号之前,是不能关闭外面的括号的。 4 所有的特性都必须有值。 5 所有的特性都必须在值的周围加上双引号。 这些规则使得开发一个XML解析器要简便得多,而且也除去了解析SGML中花在判断何时何地应用那些奇怪语法规则上的工作。仅仅在XML出现后的前六年就衍生出多种不同的语言,包括MathML、SVG、RDF、RSS、SOAP、XSLT、XSL-FO,而同时也将HTML改进为XHTML。 XHTML Validator http://validator.w3.org/
codeswarm codeswarm 是个很有意思的工具,它把一个软件开发项目中开发者往代码管理工具(git/hg/svn等)提交代码的历史记录用视频的方式表现出来。
SCADA http://baike.baidu.com/view/51065.htm SCADA(Supervisory Control And Data Acquisition)系统,即数据采集与监视控制系统。SCADA系统的应用领域很广,它可以应用于电力系统、给水系统、石油、化工等领域的数据采集与监视控制以及过程控制等诸多领域。在电力系统以及电气化铁道上又称远动系统。SCADA系统是以计算机为基础的生产过程控制与调度自动化系统。它可以对现场的运行设备进行监视和控制,以实现数据采集、设备控制、测量、参数调节以及各类信号报警等各项功能。由于各个应用领域对SCADA的要求不同,所以不同应用领域的SCADA系统发展也不完全相同。 电力系统应用 在电力系统中,SCADA系统应用最为广泛,技术发展也最为成熟。它作为能量管理系统 (EMS系统) 的一个最主要的子系统,有着信息完整、提高效率、正确掌握系统运行状态、加快决策、能帮助快速诊断出系统故障状态等优势,现已经成为电力调度不可缺少的工具。它对提高电网运行的可靠性、安全性与经济效益,减轻调度员的负担,实现电力调度自动化与现代化,提高调度的效率和水平中方面有着不可替代的作用。 SCADA在铁道电气化远动系统上的应用较早,在保证电气化铁路的安全可靠供电,提高铁路运输的调度管理水平起到了很大的作用。在铁道电气化SCADA系统的发展过程中,随着计算机的发展,不同时期有不同的产品,同时我国也从国外引进了大量的SCADA产品与设备,这些都带动了铁道电气化远动系统向更高的目标发展。 SCADA在石油管道工程中占有重要的地位,如用在系统管理石油管道的顺序控制输送、设备监控、数据同步传输记录,监控管道沿线及各站控系统运行状况等。各站场的站控系统作为管道自动控制系统的现场控制单元,除完成对所处站场的监控任务外,同时负责将有关信息传送给调度控制中心并接受和执行其下达的命令,并将所有的数据记录储存。除此之外的基本功能,现在的SCADA管道系统还具备泄露检测、系统模拟、水击提前保护等新功能。 石油方面应用 目前,国外已广泛采用SCADA系统来实现对城市燃气管道的自动监控和自动保护,并已发展成为燃气管道自动控制系统的基本模式。SCADA系统的工作原理是: 根据数据采集系统获得的系统运行工况参数与设计工况参数的比较结果,然后通过由调节阀和与之配套的电动、气动、电液联动或气液联动执行机构以及检测被调参数的仪表等组成的自动调节系统对某些偏离设计工况的运行参数进行自动纠偏调节。 发展历程 SCADA (Supervisory Control and Data Acquisition) 系统,全名为数据采集与监视控制系统。SCADA系统自诞生之日起就与计算机技术的发展紧密相关。SCADA系统发展到今天已经经历了三代。 第一代是基于专用计算机和专用操作系统的SCADA系统,如电力自动化研究院为华北电网开发的SD176系统以及在日本日立公司为我国铁道电气化远动系统所设计的H-80M系统。这一阶段是从计算机运用到SCADA系统时开始到70年代。 第二代是80年代基于通用计算机的SCADA系统,在第二代中,广泛采用VAX等其它计算机以及其它通用工作站,操作系统一般是通用的UNIX操作系统。在这一阶段,SCADA系统在电网调度自动化中与经济运行分析,自动发电控制 (AGC) 以及网络分析结合到一起构成了EMS系统 (能量管理系统) 。第一代与第二代SCADA系统的共同特点是基于集中式计算机系统,并且系统不具有开放性,因而系统维护,升级以及与其它联网构成很大困难。 90年代按照开放的原则,基于分布式计算机网络以及关系数据库技术的能够实现大范围联网的EMS/SCADA系统称为第三代。这一阶段是我国SCADA/EMS系统发展最快的阶段,各种最新的计算机技术都汇集进SCADA/EMS系统中。这一阶段也是我国对电力系统自动化以及电网建设投资最大的时期,国家计划未来三年内投资2700亿元改造城乡电网可见国家对电力系统自动化以及电网建设的重视程度。 第四代SCADA/EMS系统的基础条件已经或即将具备,预计将与21世纪初诞生。该系统的主要特征是采用Internet技术、面向对象技术、神经网络技术以及JAVA技术等技术,继续扩大SCADA/EMS系统与其它系统的集成,综合安全经济运行以及商业化运营的需要。 SCADA系统在电气化铁道远动系统的应用技术上已经取得突破性进展,应用上也有迅猛的发展。由于电气化铁道与电力系统有着不同的特点,在SCADA系统的发展上与电力系统的道路并不完全一样。在电气化铁道远动系统上已经成熟的产品有由我所自行研制开发的HY200微机远动系统以及由西南交通大学开发的DWY微机远动系统等。这些系统性能可靠、功能强大,在保证电气化铁道供电安全,提高供电质量上起到了重要的作用,对SCADA系统在铁道电气化上的应用功不可没。 发展瞻望 SCADA系统在不断完善,不断发展,其技术进步一刻也没有停止过。当今,随着电力系统以及铁道电气化系统对SCADA系统需求的提高以及计算机技术的发展,为SCADA系统提出新的要求,概括地说,有以下几点: 1.SCADA/EMS系统与其它系统的广泛集成 SCADA系统是电力系统自动化的实时数据源,为EMS系统提供大量的实时数据。同时在模拟培训系统,MIS系统等系统中都需要用到电网实时数据,而没有这个电网实时数据信息,所有其它系统都成为"无源之水"。所以在这今十年来,SCADA系统如何与其它非实时系统的连接成为SCADA研究的重要课题;现在在SCADA系统已经成功地实现与DTS (调度员模拟培训系统) 、 企业MIS系统的连接。SCADA系统与电能量计量系统,地理信息系统、水调度自动化系统、调度生产自动化系统以及办公自动化系统的集成成为SCADA系统的一个发展方向。 2.变电所综合自动化 以RTU、微机保护装置为核心,将变电所的控制、信号、测量、计费等回路纳入计算机系统,取代传统的控制保护屏,能够降低变电所的占地面积和设备投资,提高二次系统的可靠性。变电所的综合自动化已经成为有关方面的研究课题,我国东方电子等公司已经推出相应的产品,但在铁道电气化上还处于研究阶段。 3.新技术研究与应用 专家系统、模糊决策、神经网络等新技术研究与应用 利用这些新技术模拟电网的各种运行状态,并开发出调度辅助软件和管理决策软件,由专家系统根据不同的实际情况推理出最优化的运行方式或出来故障的方法,以达到合理、经济地进行电网电力调度,提高运输效率的目的。 4.面向对象、Internet、及JAVA的应用 面向对象技术 (OOT) 是网络数据库设计、市场模型设计和电力系统分析软件设计的合适工具,将面向对象技术 (OOT) 运用于SCADA/EMS系统是发展趋势。 随着Internet技术的发展,浏览器界面已经成为计算机桌面的基本平台,将浏览器技术运用于SCADA/EMS系统,将浏览器界面作为电网调度自动化系统的人机界面,对扩大实时系统的应用范围,减少维护工作量非常有利;在新一代的SCADA/EMS系统中,传统的MMI界面将保留,主要供调度员使用,新增设的Web服务器供非实时用户浏览,以后将逐渐统一为一种人机界面。 JAVA语言综合了面向对象技术和Internet技术,将编译和解释有机结合,严格实现了面向对象的四大特性: 封装性、多态性、继承性、动态联编,并在多线程支持和安全性上优于C++,以及其它诸多特性,JAVA技术将导致EMS/SCADA系统的一场革命。 5.3D scada 3D组态软件,全称3D组态监控软件系统软件。英文简写3DSCADA (3D Supervisory Control and Data Acquisition(三维数据采集与监视控制),它处于自动化控制系统的最高一级平台,一般包括开发环境和应用环境两部分。3D组态能够以灵活的组态方式,为用户提供快速构建工业自动控制系统监控功能的、通用层次的组态软件工具。3D组态软件通过三维立体监控设备达到用户如身临其景的感觉,使得人机界面控制更加逼真,更具人性化。3D组态软件的应用领域很广,可以应用于电力系统、给水系统、石油、化工、冶金等领域的数据采集与监视控制以及过程控制等诸多领域。 态神3DSCADA 也将更多的应用在各个领域! 随着工业自动化水平的迅速提高, 传统的组态软件已经日益不能满足人们的需求,程序员和操作员期待更先进的自动化软件出现,3D是这个时代产物,3D被应用在组态软件领域也就顺利成章。 3D利用DirectX/OpenGL开发,程序员可以通过简单的方法组态3D立体画面,将所有需要监测的部位放置于3D画面上,达到多方位立体监测的功能。 泄漏监测系统 SCADA泄漏监测系统 (以一条管线为例) 由变送器,服务器,远程客户端,通信网络等部分组成,如图A 所示。目前安装在长输管线上的变送器主要有压力变送器、温度变送器和流量变送器几种。需要指出的是,国内大部分管线两端都未安装流量变送器。 通信网络是系统内部信息传输的物理途径。F9G与上层服务器进行通信及数据传输、远程客户端对服务器数据库的访问以及对服务器的0') 访问均是通过通信网络进行的。该系统可基于局域网、光纤及电话线、微波等不同类型的通信方式,具有良好的适应能力。此外,系统提供了0') 访问功能,使得任何一台与服务器建立了网络连接并且安装有ST 或其他网络浏览器的计算机均可成为系统的0') 客户。 该系统应用在某油田输油管线上取得了显著的成效,系统的使用大大提高了油田生产和管理的自动化水平,为油田创造了明显的经济效益和社会效益。
SOA 面向服务的体系结构 (Service-Oriented Architecture,SOA) 是一个组件模型,它将应用程序的不同功能单元 (称为服务) 通过这些服务之间定义良好的接口和契约联系起来。接口是采用中立的方式进行定义的,它应该独立于实现服务的硬件平台、操作系统和编程语言。这使得构建在各种这样的系统中的服务可以一种统一和通用的方式进行交互。它可以根据需求通过网络对松散耦合的粗粒度应用组件进行分布式部署、组合和使用。服务层是SOA的基础,可以直接被应用调用,从而有效控制系统中与软件代理交互的人为依赖性。 SOA是一种粗粒度、松耦合服务架构,服务之间通过简单、精确定义接口进行通讯,不涉及底层编程接口和通讯模型。SOA可以看作是B/S模型、XML/Web Service技术之后的自然延伸。 SOA将能够帮助软件工程师们站在一个新的高度理解企业级架构中的各种组件的开发、部署形式,它将帮助企业系统架构者以更迅速、更可靠、更具重用性架构整个业务系统。较之以往,以SOA架构的系统能够更加从容地面对业务的急剧变化。 面向服务的体系结构 松耦合的系统 这种具有中立的接口定义 (没有强制绑定到特定的实现上) 的特征称为服务之间的松耦合。松耦合系统的好处有两点,一点是它的灵活性,另一点是,当组成整个应用程序的每个服务的内部结构和实现逐渐地发生改变时,它能够继续存在。而另一方面,紧耦合意味着应用程序的不同组件之间的接口与其功能和结构是紧密相连的,因而当需要对部分或整个应用程序进行某种形式的更改时,它们就显得非常脆弱。 对松耦合的系统的需要来源于业务应用程序需要根据业务的需要变得更加灵活,以适应不断变化的环境,比如经常改变的政策、业务级别、业务重点、合作伙伴关系、行业地位以及其他与业务有关的因素,这些因素甚至会影响业务的性质。我们称能够灵活地适应环境变化的业务为按需 (On demand) 业务,在按需业务中,一旦需要,就可以对完成或执行任务的方式进行必要的更改。 虽然面向服务的体系结构不是一个新鲜事物,但它却是更传统的面向对象的模型的替代模型,面向对象的模型是紧耦合的,已经存在二十多年了。虽然基于 SOA 的系统并不排除使用面向对象的设计来构建单个服务,但是其整体设计却是面向服务的。由于它考虑到了系统内的对象,所以虽然 SOA 是基于对象的,但是作为一个整体,它却不是面向对象的。不同之处在于接口本身。SOA 系统原型的一个典型例子是通用对象请求代理体系结构 (Common Object Request Broker Architecture,CORBA) ,它已经出现很长时间了,其定义的概念与 SOA 相似。 然而,现在的 SOA 已经有所不同了,因为它依赖于一些更新的进展,这些进展是以可扩展标记语言 (eXtensible Markup Language,XML) 为基础的。通过使用基于 XML 的语言 (称为 Web 服务描述语言 (Web Services Definition Language,WSDL) ) 来描述接口,服务已经转到更动态且更灵活的接口系统中,非以前 CORBA 中的接口描述语言 (Interface Definition Language,IDL) 可比了。 Web 服务并不是实现 SOA 的惟一方式。前面刚讲的 CORBA 是另一种方式,这样就有了面向消息的中间件 (Message-Oriented Middleware) 系统,比如 IBM 的 MQseries。但是为了建立体系结构模型,您所需要的并不只是服务描述。您需要定义整个应用程序如何在服务之间执行其工作流。您尤其需要找到业务的操作和业务中所使用的软件的操作之间的转换点。因此,SOA 应该能够将业务的商业流程与它们的技术流程联系起来,并且映射这两者之间的关系。例如,给供应商付款的操作是商业流程,而更新您的零件数据库,以包括进新供应的货物却是技术流程。因而,工作流还可以在 SOA 的设计中扮演重要的角色。 此外,动态业务的工作流不仅可以包括部门之间的操作,甚至还可以包括与不为您控制的外部合作伙伴进行的操作。因此,为了提高效率,您需要定义应该如何得知服务之间的关系的策略,这种策略常常采用服务级协定和操作策略的形式。 最后,所有这些都必须处于一个信任和可靠的环境之中,以同预期的一样根据约定的条款来执行流程。因此,安全、信任和可靠的消息传递应该在任何 SOA 中都起着重要的作用。 体系结构作用 我可以用面向服务的体系结构做什么? 对 SOA 的需要来源于需要使业务 IT 系统变得更加灵活,以适应业务中的改变。通过允许强定义的关系和依然灵活的特定实现,IT 系统既可以利用现有系统的功能,又可以准备在以后做一些改变来满足它们之间交互的需要。 下面举一个具体的例子。一个服装零售组织拥有 500 家国际连锁店,它们常常需要更改设计来赶上时尚的潮流。这可能意味着不仅需要更改样式和颜色,甚至还可能需要更换布料、制造商和可交付的产品。如果零售商和制造商之间的系统不兼容,那么从一个供应商到另一个供应商的更换可能就是一个非常复杂的软件流程。通过利用 WSDL 接口在操作方面的灵活性,每个公司都可以将它们的现有系统保持现状,而仅仅匹配 WSDL 接口并制订新的服务级协定,这样就不必完全重构它们的软件系统了。这是业务的水平改变,也就是说,它们改变的是合作伙伴,而所有的业务操作基本上都保持不变。这里,业务接口可以作少许改变,而内部操作却不需要改变,之所以这样做,仅仅是为了能够与外部合作伙伴一起工作。 另一种形式是内部改变,在这种改变中,零售组织现在决定它还将把连锁零售商店内的一些地方出租给专卖流行衣服的小商店,这可以看作是采用店中店 (store-in-store) 的业务模型。这里,虽然公司的大多数业务操作都保持不变,但是它们现在需要新的内部软件来处理这样的出租安排。尽管在内部软件系统可以承受全面的检修,但是它们需要在这样做的同时不会对与现有的供应商系统的交互产生大的影响。在这种情况下,SOA 模型保持原封不动,而内部实现却发生了变化。虽然可以将新的方面添加到 SOA 模型中来加入新的出租安排的职责,但是正常的零售管理系统继续如往常一样。 为了延续内部改变的观念,IT 经理可能会发现,软件的新配置还可以以另外的一种方式加以使用,比如出租粘贴海报的地方以供广告之用。这里,新的业务提议是通过在新的设计中重用灵活的 SOA 模型得出的。这是来自 SOA 模型的新成果,并且还是一个新的机会,而这样的新机会在以前可能是不会有的。 垂直改变也是可能的,在这种改变中,零售商从销售他们自己的服装完全转变到专门通过店中店模型出租地方。如果垂直改变完全从最底层开始的话,就会带来 SOA 模型结构的显著改变,与之一起改变的还可能有新的系统、软件、流程以及关系。在这种情况下,SOA 模型的好处是它从业务操作和流程的角度考虑问题而不是从应用程序和程序的角度考虑问题,这使得业务管理可以根据业务的操作清楚地确定什么需要添加、修改或删除。然后可以将软件系统构造为适合业务处理的方式,而不是在许多现有的软件平台上常常看到的其他方式。 正如您可以看到的,在这里,改变和 SOA 系统适应改变的能力是最重要的部分。对于开发人员来说,这样的改变无论是在他们工作的范围之内还是在他们工作的范围之外都有可能发生,这取决于是否有改变需要知道接口是如何定义的以及它们相互之间如何进行交互。与开发人员不同的是,架构师的作用就是引起对 SOA 模型大的改变。这种分工,就是让开发人员集中精力于创建作为服务定义的功能单元,而让架构师和建模人员集中精力于如何将这些单元适当地组织在一起,它已经有十多年的历史了,通常用统一建模语言 (Universal Modeling Language,UML) ,并且描述成模型驱动的体系结构 (Model-Driven Architecture,MDA) 。 对于面向同步和异步应用的,基于请求/响应模式的分布式计算来说,SOA是一场革命。一个应用程序的业务逻辑 (business logic) 或某些单独的功能被模块化并作为服务呈现给消费者或客户端。这些服务的关键是他们的松耦合特性。例如,服务的接口和实现相独立。应用开发人员或者系统集成者可以通过组合一个或多个服务来构建应用,而无须理解服务的底层实现。举例来说,一个服务可以用.NET或J2EE来实现,而使用该服务的应用程序可以在不同的平台之上,使用的语言也可以不同。 SOA与互联网 Service-Oriented Device Architecture (SODA),即"面向服务的设备架构",是一个由IBM和美国Florida大学发起的倡议(Initiative)和联盟(Alliance),通过引入基于服务 (SOA) 的编程模型,以规范和简化智能设备 (Devices) 与企业应用的集成。SODA致力于充分利用嵌入式系统和IT领域已有的标准,为智能设备与SOA技术的融合提供一个标准平台。 SODA的目标是让软件开发者能够像用SOA技术实现IT业务集成那样在诸如远程医疗、军事、以及RFID等物联网系统中实现与传感器和执行器的集成[1]。 具体来说,SODA提供标准接口,把硬件设备功能转换成与硬件无关的可调用的软件服务,实现如下目标: 1. 实现应用集成商与设备和传感器制造商的无缝对接; 2. Integrate once, deploy everywhere, 使用户专注于整体应用方案而不是陷于设备连接工作; 3. 在应用和众多 (泛在) 设备协议之间建立一个通用接口和DDL,形成统一数据交换标准; 4. 作为一个中间件平台,为众多行业应用提供应用支持。 SODA架构 ...
nexus OSS # docker docker run \ -d \ --name nexus \ -p 30081:8081 \ -p 30083:8083 \ -v /etc/localtime:/etc/localtime:ro \ -v nexus-data:/nexus-data \ -e INSTALL4J_ADD_VM_PARAMS="-Xms128m -Xmx512m -XX:MaxDirectMemorySize=256m" \ sonatype/nexus3:3.65.0 # podman podman run \ -d \ --name nexus \ -p 30081:8081 \ -p 30083:8083 \ -v /etc/localtime:/etc/localtime:ro \ -v nexus-data:/nexus-data \ -e INSTALL4J_ADD_VM_PARAMS=-Xms128m -Xmx256m -XX:MaxDirectMemorySize=256m \ sonatype/nexus3:3.39.0 config default username/password=admin/admin123 Blob Stores/Enable Soft Quota: 限制目录大小 download nexus-2.14.0-01-bundle.zip unzip and execute ./bin/nexus start add aliyun repo as proxy repository repository id: aliyun_repo repository name: aliyun_repo provider Maven2 ...
no such file to load — mkmf Building native extensions. This could take a while... ERROR: Error installing rails: ERROR: Failed to build gem native extension. /usr/bin/ruby1.8 extconf.rb extconf.rb:1:in \`require': no such file to load - mkmf (LoadError) from extconf.rb:1 For some reason, mkmf.rb is part of the ruby1.8-dev package, and initially I hadn’t installed that. #install ruby1.8-dev sudo apt-get install ruby1.8-dev and everything trotted along happily after that.
Foo 是什么意思 http://www.cnblogs.com/felicity/archive/2010/11/30/1892100.html 不管是java,C++,还是PHP,每次都能看到 foo = bar 的例子,这两个单词很恶心,foo查不到字典,bar的解释又让人跟编程联系不上,更弄不清楚这个神秘的foo是个什么关系。 语意不清,学起来心里老是有疙疙瘩瘩的感觉,于是查吧,终于揭开了这两个东西的不正常关系,讲个各个处在闹心中的初学者们听吧。 参考了众多的网络资料,最后,明确的告诉大家,foo和bar就是外国人的张三、李四、王二麻子,只是一种随便的命名方式。跟c语言里面的i,j,k同出一辙。 就是说foo = bar 跟 变量张三 = 李四的侄子 一个意图,所以童鞋们就不要再找foo到底是个啥了。 问foo是啥就跟问张三是谁一样,我想外国人一定也很想知道,张三到底是谁,这个人怎么这么有名,总能看到这个名字,但是历史上记载却又找不到他。 为了这个可恶的foo,居然还动用RFC给foo下了一个明确的词源追踪,无聊的童鞋可以看RFC3092解解闷。 https://www.ietf.org/rfc/rfc3092.txt 下面是网上搜刮来的各种解释: Foo: 本意指程序员用来代表数据、功能或命令的变量。O’Reilly媒体认为FOO是Friends of O’Reilly的缩写,并把他们在2003年举办的年会命名为"2003 FOO"。现在则更多地指声势浩大的某行业大会。 foo = fuck oriented object foo是"你要让它是什么就是什么"。FOO可以具有用户赋于的任何意义。 foo—–潦草的意思!表示很随便的定义! foo没有意义 foo的意思是:Factory Of Objects foo: 一塌糊涂或者bar: 一团糟 foo 不同的字典对其解释相去甚远,一说来自中国"福"字的发音,又有解释为二战时期的一种武器。然而若把众多的解释放在编程领域,关于 foobar的说法是我认为最为贴切的解释。foobar又为foo-bar,其中bar是beyond all recognition的缩写,通俗点就是无法识别,一塌糊涂的意思。而foo是fu的变体,fu是英语习语fuck-up的缩写,同样是一团糟的意思。于是,若你有些编程经验,我想你应该已经明白了为何如今许多编程实例所涉及的事物均被冠名为foo. 介绍 至今约有212 个RFC, 或者约7%的RFC, 从[RFC269]开始,包括了术语’foo’,‘bar’ 或’foobar’作为伪变量而没有任何适当的解释或定义。这可能被认为是微不足道的,但一些新来者,特别是那些非英语国家的人,在理解这些术语时会遇到困难。本文纠正这一问题。 定义和语源 bar /bar/ n. [JARGON] 第二个伪变量,在foo 之后而在baz 之前。 “Suppose we have two functions: FOO and BAR. FOO calls BAR….” ...
http://www.infoq.com/cn/articles/cf-javaone-2011-cdi-google-dart CDI 对于依赖注入的概念,相信很多开发人员都不陌生。一个组件在运行过程中会依赖其他组件提供的功能。传统的做法是由组件本身负责查找所需的依赖对象。这种方式会造成组件之间的紧耦合,不利于组件的维护和更新。依赖注入的做法则是由组件以声明式的方式表明其依赖关系,由框架在运行时把所需的组件的Java对象注入到当前组件中。相对于Java SE来说,依赖注入的概念对于Java EE更加适用。Java EE中的很多资源和服务都是由容器来负责管理的。对于单个应用来说,查找由容器负责管理的组件并不是一件容易的事情。更好的做法是由应用来声明所需的资源和服务,由容器负责注入到应用中。通过这种方式,容器也可以更好的对资源和服务进行管理。以数据库连接为例,传统的做法需要由应用本身加载相关驱动并创建数据库连接,以及在适当的时候进行释放。而使用容器管理并注入依赖的做法,则减轻了应用开发人员的工作量。 Java EE 5中添加了对依赖注入的有限支持。通过注解可以往容器管理的对象中注入资源的对应对象。Java EE 6中把依赖注入的概念更进一步,即引入了JSR 299 (Contexts and Dependency Injection for the Java EE platform)规范,简称CDI。CDI规范吸收了来自Spring IoC容器、JBoss Seam和Google Guice的最佳实践,并与Java EE开发的实际需要相结合。正如CDI的字面含义一样,CDI中的两个核心功能是上下文信息 (context) 和依赖注入。这两个功能的结合点是Java中基本的组件模型bean。在CDI中,bean 定义了应用的状态和逻辑,并由容器来进行管理。每个被管理的bean都有定义好的绑定到特定上下文的作用域和生命周期。当需要注入或访问bean时,容器会从作用域对应的上下文中获取。当作用域失效时,对应上下文中所有的对象都会被删除。CDI中的每个bean都可以作为依赖注入时的目标。 CDI中预定义了一些常用的作用域。默认的作用域是Dependent,表示只对被注入的对象生效。作用域ApplicationScoped表示应用的全局作用域,用来创建全局唯一的对象。RequestScoped和SessionScoped则与HTTP相关,分别表示HTTP请求和HTTP会话。ConversationScoped是由应用自定义生命周期长短的作用域,可以用来实现跨多页面的工作流。如下面代码中的OrderProcessor类只存活在HTTP请求中,并且依赖OrderDao接口的实现。容器会在运行时查找到OrderDao接口的实现对象,并注入到OrderProcessor类的对象中。 @Named @RequestScoped public class OrderProcessor { @Inject private OrderDao orderDao; } 通常的依赖注入方式是在代码中只依赖接口,由容器在运行时选择合适的实现类的对象来进行注入。如果接口只有一个实现类,则不需要额外的声明。如果接口有不同的实现,则需要使用限定符 (qualifier) 来声明具体使用的实现,否则容器无法做出正确的选择。CDI的一个特点是限定符不是普通的字符串,而是类型安全的注解。 通过Qualifier元注解可以创建新的限定符注解。如下面的代码创建了一个新的限定符注解InMemory。 @Qualifier @Retention(RUNTIME) @Target({TYPE}) public @interface InMemory {} 该注解可以添加在OrderDao接口的实现上。 @InMemory public class InMemoryOrderDao implements OrderDao { } 如果在测试时,希望使用简单的基于内存的存储实现,可以使用InMemory注解来声明。这样容器在注入时会使用InMemoryOrderDao类的对象。 @Named @RequestScoped public class OrderProcessor { @Inject @InMemory private OrderDao orderDao; } ...
Spring的静态工厂方法 http://blog.csdn.net/chensugang/article/details/3357593 上一次写了一篇关于DI的三种方式,其中里面介绍了构造方法的方式,今天学习了一种替代构造器的方法,这就是静态工厂方法来返回对象,下面来看一下静态工厂方法的实现。 静态工厂方法: LoginAction类: package com.spring.test.di; public class LoginAction { private Logic logic; private LoginAction(Logic logic){ this.logic = logic; } public static LoginAction createInstance(Logic logic){ LoginAction loginAction = new LoginAction (logic); return loginAction; } public void execute() { String name = logic.getName(); System.out.print(“My Name Is " + name); } } 注意: 这里使用的构造方法是一个私有方法,createInstance这个就是我们的静态工厂方法 Logic接口: package com.spring.test.di; public interface Logic { public String getName(); } 这里只是做为一个简单的例子,所以我们在该接口中只有一个方法,并且在该接口的实现方法也超级简单 Logic接口实现: package com.spring.test.di; public class LogicImpl implements Logic{ public String getName(){ return “fengyun”; ...
static factory method 创建类的实例的最常见的方式是用new语句调用类的构造方法。在这种情况下,程序可以创建类的任意多个实例,每执行一条new语句,都会导致Java虚拟机的堆区中产生一个新的对象。假如类需要进一步封装创建自身实例的细节,并且控制自身实例的数目,那么可以提供静态工厂方法。 例如Class实例是Java虚拟机在加载一个类时自动创建的,程序无法用new语句创建java.lang.Class类的实例,因为Class类没有提供public类型的构造方法。为了使程序能获得代表某个类的Class实例,在Class类中提供了静态工厂方法forName(String name),它的使用方式如下: Class c=Class.forName( “Sample “); //返回代表Sample类的实例 静态工厂方法与用new语句调用的构造方法相比,有以下区别。 (1) 构造方法的名字必须与类名相同。这一特性的优点是符合Java语言的规范,缺点是类的所有重载的构造方法的名字都相同,不能从名字上区分每个重载方法,容易引起混淆。 静态工厂方法的方法名可以是任意的,这一特性的优点是可以提高程序代码的可读性,在方法名中能体现与实例有关的信息。例如例程11-5的Gender类有两个静态工厂方法: getFemale()和getMale()。 例程11-5 Gender.java public class Gender{ private String description; private static final Gender female=new Gender( “女 “); private static final Gender male=new Gender( “男 “); private Gender(String description){this.description=description;} public static Gender getFemale(){ return female; } public static Gender getMale(){ return male; } public String getDescription(){return description;} } 这一特性的缺点是与其他的静态方法没有明显的区别,使用户难以识别类中到底哪些静态方法专门负责返回类的实例。为了减少这一缺点带来的负面影响,可以在为静态工厂方法命名时尽量遵守约定俗成的规范,当然这不是必需的。目前比较流行的规范是把静态工厂方法命名为valueOf或者getInstance。 l valueOf: 该方法返回的实例与它的参数具有同样的值,例如: Integer a=Integer.valueOf(100); //返回取值为100的Integer对象 从上面代码可以看出,valueOf()方法能执行类型转换操作,在本例中,把int类型的基本数据转换为Integer对象。 l getInstance: 返回的实例与参数匹配,例如: ...