﻿<?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>BlogJava-Chan Chen Coding...-文章分类-Architecture</title><link>http://www.blogjava.net/czihong/category/50909.html</link><description /><language>zh-cn</language><lastBuildDate>Thu, 16 May 2013 10:15:52 GMT</lastBuildDate><pubDate>Thu, 16 May 2013 10:15:52 GMT</pubDate><ttl>60</ttl><item><title>Java MVC 比较</title><link>http://www.blogjava.net/czihong/articles/398790.html</link><dc:creator>Chan Chen</dc:creator><author>Chan Chen</author><pubDate>Sat, 04 May 2013 08:21:00 GMT</pubDate><guid>http://www.blogjava.net/czihong/articles/398790.html</guid><wfw:comment>http://www.blogjava.net/czihong/comments/398790.html</wfw:comment><comments>http://www.blogjava.net/czihong/articles/398790.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/czihong/comments/commentRss/398790.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/czihong/services/trackbacks/398790.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: Spring MVC&nbsp;PK&nbsp;Struts2我们用struts2时采用的传统的配置文件的方式，并没有使用传说中的0配置。spring3 mvc可以认为已经100%零配置了（除了配置spring mvc-servlet.xml外）。Spring MVC和Struts2的区别：1. 机制：spring mvc的入口是servlet，而struts2是filter（...&nbsp;&nbsp;<a href='http://www.blogjava.net/czihong/articles/398790.html'>阅读全文</a><img src ="http://www.blogjava.net/czihong/aggbug/398790.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/czihong/" target="_blank">Chan Chen</a> 2013-05-04 16:21 <a href="http://www.blogjava.net/czihong/articles/398790.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>计算500万PV/每天的网站</title><link>http://www.blogjava.net/czihong/articles/398789.html</link><dc:creator>Chan Chen</dc:creator><author>Chan Chen</author><pubDate>Sat, 04 May 2013 08:00:00 GMT</pubDate><guid>http://www.blogjava.net/czihong/articles/398789.html</guid><wfw:comment>http://www.blogjava.net/czihong/comments/398789.html</wfw:comment><comments>http://www.blogjava.net/czihong/articles/398789.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/czihong/comments/commentRss/398789.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/czihong/services/trackbacks/398789.html</trackback:ping><description><![CDATA[<p style="margin: 0px; padding: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.1875px; background-color: #ffffff;"><span style="font-size: medium;">Refer to:&nbsp;</span><a href="http://elf8848.iteye.com/blog/967049">http://elf8848.iteye.com/blog/967049</a><br /><span style="font-size: medium;">你想建设一个能承受500万PV/每天的网站吗？ 500万PV是什么概念？服务器每秒要处理多少个请求才能应对？如果计算呢？&nbsp;<br /><br /><strong>PV是什么：</strong></span></p><p style="margin: 0px; padding: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.1875px; background-color: #ffffff;"><span style="font-size: medium;">PV是page view的简写。PV是指页面的访问次数，每</span><span style="font-size: medium;">打开或刷新</span><span style="font-size: medium;">一次页面，就算做一个pv。&nbsp;<br /><br /><strong>计算模型：&nbsp;</strong><br />每台服务器每秒处理请求的数量=((80%*总PV量)/(24小时*60分*60秒*40%)) / 服务器数量 。<br />其中关键的参数是80%、40%。表示一天中有80%的请求发生在一天的40%的时间内。24小时的40%是9.6小时，有80%的请求发生一天的9.6个小时当中（很适合互联网的应用，白天请求多，晚上请求少）。&nbsp;<br /></span></p><p style="margin: 0px; padding: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.1875px; background-color: #ffffff;">&nbsp;</p><p style="margin: 0px; padding: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.1875px; background-color: #ffffff;"><span style="font-size: medium;"><strong>简单计算的结果：</strong><br />((80%*500万)/(24小时*60分*60秒*40%))/1 = 115.7个请求/秒&nbsp;<br />((80%*100万)/(24小时*60分*60秒*40%))/1 = 23.1个请求/秒&nbsp;<br /><br /><strong>初步结论：</strong>&nbsp;<br />现在我们在做压力测试时，就有了标准，如果你的服务器一秒能处理115.7个请求，就可以承受500万PV/每天。如果你的服务器一秒能处理23.1个请求，就可以承受100万PV/每天</span><span style="font-size: medium;">。</span></p><p style="margin: 0px; padding: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.1875px; background-color: #ffffff;">&nbsp;</p><p style="margin: 0px; padding: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.1875px; background-color: #ffffff;"><span style="font-size: medium;"><strong>留足余量：</strong></span></p><p style="margin: 0px; padding: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.1875px; background-color: #ffffff;"><span style="font-size: medium;">以上请求数量</span><span style="font-size: medium;">是</span><span style="font-size: medium;">均匀的分布在白天的9.6个小时中，但实际情况并不会这么均匀的分布，会有高峰有低谷。为了应对高峰时段，</span><span style="font-size: medium;">应该留一些余地，最少也要x2倍，x3倍也不为过。</span></p><p style="margin: 0px; padding: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.1875px; background-color: #ffffff;"><span style="font-size: medium;">115.7个请求/秒&nbsp;*2倍=231.4</span><span style="font-size: medium;">个请求/秒</span></p><p style="margin: 0px; padding: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.1875px; background-color: #ffffff;"><span style="font-size: medium;">115.7个请求/秒&nbsp;*3</span><span style="font-size: medium;">倍</span><span style="font-size: medium;">=347.1</span><span style="font-size: medium;">个请求/秒</span></p><p style="margin: 0px; padding: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.1875px; background-color: #ffffff;"><span style="font-size: medium;">23.1个请求/秒&nbsp;*2</span><span style="font-size: medium;">倍</span><span style="font-size: medium;">=46.2</span><span style="font-size: medium;">个请求/秒</span></p><p style="margin: 0px; padding: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.1875px; background-color: #ffffff;"><span style="font-size: medium;">23.1个请求/秒&nbsp;*3</span><span style="font-size: medium;">倍</span><span style="font-size: medium;">=</span><span style="font-size: medium;">69.3</span><span style="font-size: medium;">个请求/秒</span></p><p style="margin: 0px; padding: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.1875px; background-color: #ffffff;">&nbsp;</p><p style="margin: 0px; padding: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.1875px; background-color: #ffffff;"><strong style="font-size: medium;">最终结论：</strong></p><p style="margin: 0px; padding: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.1875px; background-color: #ffffff;"><span style="font-size: medium;">如果你的服务器一秒能处理</span><span style="font-size: medium;">231.4--</span><span style="font-size: medium;">347.1</span><span style="font-size: medium;">个请求/秒</span><span style="font-size: medium;">，就可以应对平均500万PV/每天。</span></p><p style="margin: 0px; padding: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.1875px; background-color: #ffffff;"><span style="font-size: medium;">如果你的服务器一秒能处理</span><span style="font-size: medium;">46.2--</span><span style="font-size: medium;">69.3</span><span style="font-size: medium;">个请求，就可以</span><span style="font-size: medium;">应对平均100万PV/每天</span><span style="font-size: medium;">。</span></p><p style="margin: 0px; padding: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.1875px; background-color: #ffffff;">&nbsp;</p><p style="margin: 0px; padding: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.1875px; background-color: #ffffff;"><span style="font-size: medium;"><strong>说明：</strong></span></p><p style="margin: 0px; padding: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.1875px; background-color: #ffffff;"><span style="font-size: medium;">这里说明每秒N个请求，就是QPS。因为我关心的是应用程序处理业务的能力。&nbsp;</span></p><p style="margin: 0px; padding: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.1875px; background-color: #ffffff;">&nbsp;</p><p style="margin: 0px; padding: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.1875px; background-color: #ffffff;"><span style="font-size: medium;"><strong>实际经验：</strong></span></p><p style="margin: 0px; padding: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.1875px; background-color: #ffffff;"><span style="font-size: medium;">1、根据实际经验，采用两台常规配置的机架式服务器，配置是很常见的配置，例如一个4核CPU+4G内存+服务器SAS硬盘</span><span style="font-size: medium;">。</span></p><p style="margin: 0px; padding: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.1875px; background-color: #ffffff;"><span style="font-size: medium;">2、个人武断的认为在服务器CPU领域Intel的CPU要优于AMD</span><span style="font-size: medium;">的CPU</span><span style="font-size: medium;">，有反对的就反对吧，我都说我武断了（请看</span><a href="http://elf8848.iteye.com/blog/710950" style="color: #108ac6; font-size: medium;">CPU性能比较</a><span style="font-size: medium;">），不要太相信AMD的广告，比较CPU性能简单办法就是比价格，不要比频率与核心数，价格相差不多的性能也相差不多。</span></p><p style="margin: 0px; padding: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.1875px; background-color: #ffffff;"><span style="font-size: medium;">3、硬盘的性能很重要，由其是数据库服务器。一般的服务器都配</span><span style="font-size: medium;">1.5万转的SAS硬盘，高级一点的可以配SSD固态硬盘，性能会更好。最最最最重要的指标是&#8220;随机读写性能&#8221;而不是&#8220;顺序读写性能&#8221;。（本例还是配置最常见的</span><span style="font-size: medium;">1.5万转的SAS硬盘吧</span><span style="font-size: medium;">）</span></p><p style="margin: 0px; padding: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.1875px; background-color: #ffffff;"><span style="font-size: medium;">4、一台服务器跑Tomcat运行j2ee程序,一台服务器跑MySql数据库,程序写的中等水平(这个真的不好量化)，是</span><span style="font-size: medium;">论坛类型的应用(总有回帖,不太容易做缓存,也无法静态化)。</span></p><p style="margin: 0px; padding: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.1875px; background-color: #ffffff;"><span style="font-size: medium;">5、以上软硬件情况下，是可以承受100万PV/每天的。(已留有余量应对突然的访问高峰)</span></p><p style="margin: 0px; padding: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.1875px; background-color: #ffffff;">&nbsp;</p><p style="margin: 0px; padding: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.1875px; background-color: #ffffff;"><span style="font-size: medium;"><strong>注意机房的网络带宽：</strong></span></p><p style="margin: 0px; padding: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.1875px; background-color: #ffffff;"><span style="font-size: medium;">有人说以上条件我都满足了，但实际性能还是达不到目标。这时请注意你对外的网络的带宽，在国内服务器便宜但带宽很贵，很可能你在机房是与大家共享一条100M的光纤，实际每个人可分到2M左右带宽。再好一点5M,再好一点双线机房10M独享，这已经</span><span style="font-size: medium;">很贵</span><span style="font-size: medium;">了（北京价格）。</span></p><p style="margin: 0px; padding: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.1875px; background-color: #ffffff;"><span style="font-size: small;"><span style="font-size: medium;">一天总流量：每个页面20k字节*100万个页面/1024=19531M字节=19G字节，</span></span></p><p style="margin: 0px; padding: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.1875px; background-color: #ffffff;"><span style="font-size: small;"><span style="font-size: medium;">19531M/9.6小时=2034M/小时=578K字节/s &nbsp; 如果请求是均匀分布的，需要5M</span></span><span style="font-size: small;">（</span><span style="font-size: medium;">640K字节</span><span style="font-size: medium;">）</span><span style="font-size: medium;">带宽（5Mb=640KB 注意大小写，b是位，B是字节，差了8倍）</span><span style="font-size: medium;">，但所有请求不可能是均匀分布的，当有高峰时5M带宽一定不够，X2倍就是10M带宽。</span><span style="font-size: medium;">10M带宽</span><span style="font-size: medium;">基本可以满足要求。</span></p><p style="margin: 0px; padding: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.1875px; background-color: #ffffff;"><span style="font-size: medium;">以上是假设每个页面20k字节，基本不包含图片，要是</span><span style="font-size: medium;">包含</span><span style="font-size: medium;">图片就更大了，10M</span><span style="font-size: medium;">带宽</span><span style="font-size: medium;">也不能满足要求了。你自已计算吧。</span></p><p style="margin: 0px; padding: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.1875px; background-color: #ffffff;"><span style="font-size: medium;">（全文完）</span></p><p style="margin: 0px; padding: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.1875px; background-color: #ffffff;">&nbsp;</p><p style="margin: 0px; padding: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.1875px; background-color: #ffffff;">&nbsp;</p><p style="margin: 0px; padding: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.1875px; background-color: #ffffff;">&nbsp;</p><p style="margin: 0px; padding: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.1875px; background-color: #ffffff;"><span style="font-size: medium;"><strong>附：性能测试基本概念</strong><br />---------------------------------------------------------------------------------------&nbsp;<br /><strong>基本概念：</strong>&nbsp;<br />Throughput（吞吐量）：按照常规理解网络吞吐量表示在单位时间内通过网卡数据量之和，其中即包括本机网卡发送出去的数据量也包括本机网卡接收到的数据量。 一个100Mb(位)的双工网卡，最大发送数据的速度是12.5M字节/s ，</span>&nbsp;<span style="font-size: medium;">最大接收数据的速度是12.5M字节/s，</span>&nbsp;<span style="font-size: medium;">可以</span>&nbsp;<strong><span style="font-size: medium;">同时</span>&nbsp;<span style="font-size: medium;">收发</span>&nbsp;</strong><span style="font-size: medium;">数据。&nbsp;</span><br /><span style="font-size: medium;">并发用户数：是同时执行操作的用户(线程数)。&nbsp;<br />响应时间：从请求发出到收到响应花费的时间 。</span></p><p style="margin: 0px; padding: 0px; font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 25.1875px; background-color: #ffffff;"><span style="font-size: medium;"><br />QPS&nbsp;</span><span style="font-size: medium;">- Queries Per Second&nbsp;&nbsp;</span><span style="font-size: medium;">每秒处理的查询数（如果是数据库，就相当于读取）<br />TPS&nbsp;</span><span style="font-size: medium;">- Transactions Per Second&nbsp;&nbsp;</span><span style="font-size: medium;">每秒处理的事务数(如果是数据库，就相当于写入、修改)<br />IOPS，每秒磁盘进行的I/O操作次数<br /><br />例如对某个数据库测试，分开两次测QPS与TPS。<br />QPS（读取）值总是高于TPS(写、改)，并且有倍率关系，因为：<br />1、数据库对查询可能有缓存。<br />2、机械硬盘或SSD硬盘的读就是比写快。</span>&nbsp;<span style="font-size: medium;"><br />---------------------------------------------------------------------------------------&nbsp;<br /><strong>JMeter测试参数说明：</strong>&nbsp;<br /><br />Label：每一个测试单元的名字。&nbsp;<br /><br />#Samples：表示一个测试单元一共发出了多少个请求。&nbsp;<br /><br />Average：平均响应时间&#8212;&#8212;默认情况下是单个 Request 的平均响应时间，当使用了 Transaction Controller 时，也可以以Transaction 为单位显示平均响应时间。，不重要。&nbsp;<br /><br />Median：中位数，也就是 50％ 用户的响应时间，如果把响应时间从小到大顺序排序，那么50％的请求的响应时间在这个范围之内。重要。&nbsp;<br /><br />90% Line：90％ 用户的响应时间，如果把响应时间从小到大顺序排序，那么90％的请求的响应时间在这个范围之内。<span style="color: #ff0000;">重要</span>&nbsp;。&nbsp;<br /><br />Min：最小响应时间，不重要。&nbsp;<br /><br />Max：最大响应时间，出现几率只不过是千分之一甚至万分之一，不重要。&nbsp;<br /><br />Error%：本次测试中出现错误的请求的数量&nbsp;<br /><br />Throughput：吞吐量&#8212;&#8212;默认情况下表示每秒完成的请求数（Request per Second），当使用了 Transaction Controller 时，也可以表示类似 LoadRunner 的 Transaction per Second 数&nbsp;<br /><br />KB/Sec：每秒从服务器端<span style="color: #ff0000;">接收</span>&nbsp;到的数据量(只是接收)，相当于LoadRunner中的Throughput/Sec&nbsp;<br />---------------------------------------------------------------------------------------&nbsp;<br /><strong>loadrunner测试参数说明：</strong>&nbsp;<br /><br /><strong>响应时间：</strong>&nbsp;取90%值，如果把响应时间从小到大顺序排序，那么90％的请求的响应时间在这个范围之内。重要。&nbsp;<br /><br /><strong>每秒点击数</strong>&nbsp;：hits per Second,每秒钟向服务器提交请求的数量。&nbsp;<br /><br /><strong>TPS：</strong>&nbsp;Transaction per Second ，每秒事务数，一个事务是指一个客户机向服务器发送请求然后服务器做出反应的过程&nbsp;<br /><br /><strong>Throughput（吞吐量）：</strong>&nbsp;Loadrunner记录的Throughput是接收到服务器返回的所有字节数之和，与本地发出的字节数无关。&nbsp;<br /><br /><strong>Throughput/Sec：</strong>&nbsp;每秒的吞吐量。&nbsp;<br /><br />对于BS架构的一般分析 响应时间、点击率、吞吐量、TPS（每秒事务数）。&nbsp;<br />对于CS架构的一般分析 TPS（每秒事务数）&nbsp;</span></p><img src ="http://www.blogjava.net/czihong/aggbug/398789.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/czihong/" target="_blank">Chan Chen</a> 2013-05-04 16:00 <a href="http://www.blogjava.net/czihong/articles/398789.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>静态技术详解</title><link>http://www.blogjava.net/czihong/articles/396950.html</link><dc:creator>Chan Chen</dc:creator><author>Chan Chen</author><pubDate>Mon, 25 Mar 2013 02:29:00 GMT</pubDate><guid>http://www.blogjava.net/czihong/articles/396950.html</guid><wfw:comment>http://www.blogjava.net/czihong/comments/396950.html</wfw:comment><comments>http://www.blogjava.net/czihong/articles/396950.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/czihong/comments/commentRss/396950.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/czihong/services/trackbacks/396950.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: Refer to:&nbsp;http://www.cnblogs.com/funnyking/archive/2010/05/26/1744834.html一.&nbsp;什么是静态化在此之前，我们好多的人不知道什么是静态化，说得简单点，就是把所有不是.htm或者.html的页面改为.htm或者.html。我们在处理方法上，有静态化和伪静态方法，希望大家不要把两者混为一潭。当然更不要把他和纯静态...&nbsp;&nbsp;<a href='http://www.blogjava.net/czihong/articles/396950.html'>阅读全文</a><img src ="http://www.blogjava.net/czihong/aggbug/396950.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/czihong/" target="_blank">Chan Chen</a> 2013-03-25 10:29 <a href="http://www.blogjava.net/czihong/articles/396950.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>DAL</title><link>http://www.blogjava.net/czihong/articles/382970.html</link><dc:creator>Chan Chen</dc:creator><author>Chan Chen</author><pubDate>Thu, 12 Jul 2012 22:41:00 GMT</pubDate><guid>http://www.blogjava.net/czihong/articles/382970.html</guid><wfw:comment>http://www.blogjava.net/czihong/comments/382970.html</wfw:comment><comments>http://www.blogjava.net/czihong/articles/382970.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/czihong/comments/commentRss/382970.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/czihong/services/trackbacks/382970.html</trackback:ping><description><![CDATA[<p style="margin: 0.4em 0px 0.5em; line-height: 19px; font-family: sans-serif; font-size: 13px; background-color: #ffffff; ">A&nbsp;<strong>data access layer</strong>&nbsp;(DAL) in computer software, is a&nbsp;<a href="http://en.wikipedia.org/wiki/Layer_(object-oriented_design)" title="Layer (object-oriented design)" style="text-decoration: none; color: #0b0080; background-image: none; background-position: initial initial; background-repeat: initial initial; ">layer</a>&nbsp;of a&nbsp;<a href="http://en.wikipedia.org/wiki/Computer_program" title="Computer program" style="text-decoration: none; color: #0b0080; background-image: none; background-position: initial initial; background-repeat: initial initial; ">computer program</a>&nbsp;which provides simplified access to&nbsp;<a href="http://en.wikipedia.org/wiki/Data" title="Data" style="text-decoration: none; color: #0b0080; background-image: none; background-position: initial initial; background-repeat: initial initial; ">data</a>&nbsp;stored in&nbsp;<a href="http://en.wikipedia.org/wiki/Persistent_storage" title="Persistent storage" style="text-decoration: none; color: #0b0080; background-image: none; background-position: initial initial; background-repeat: initial initial; ">persistent storage</a>&nbsp;of some kind, such as an<a href="http://en.wikipedia.org/wiki/Entity_relationship" title="Entity relationship" style="text-decoration: none; color: #0b0080; background-image: none; background-position: initial initial; background-repeat: initial initial; ">entity-relational</a>&nbsp;<a href="http://en.wikipedia.org/wiki/Database" title="Database" style="text-decoration: none; color: #0b0080; background-image: none; background-position: initial initial; background-repeat: initial initial; ">database</a>.</p><p style="margin: 0.4em 0px 0.5em; line-height: 19px; font-family: sans-serif; font-size: 13px; background-color: #ffffff; ">For example, the DAL might return a reference to an&nbsp;<a href="http://en.wikipedia.org/wiki/Object_(computer_science)" title="Object (computer science)" style="text-decoration: none; color: #0b0080; background-image: none; background-position: initial initial; background-repeat: initial initial; ">object</a>&nbsp;(in terms of&nbsp;<a href="http://en.wikipedia.org/wiki/Object-oriented_programming" title="Object-oriented programming" style="text-decoration: none; color: #0b0080; background-image: none; background-position: initial initial; background-repeat: initial initial; ">object-oriented programming</a>) complete with its attributes instead of a&nbsp;<a href="http://en.wikipedia.org/wiki/Row" title="Row" style="text-decoration: none; color: #0b0080; background-image: none; background-position: initial initial; background-repeat: initial initial; ">row</a>&nbsp;of&nbsp;<a href="http://en.wikipedia.org/wiki/Field_(computer_science)" title="Field (computer science)" style="text-decoration: none; color: #0b0080; background-image: none; background-position: initial initial; background-repeat: initial initial; ">fields</a>&nbsp;from a database&nbsp;<a href="http://en.wikipedia.org/wiki/Table_(database)" title="Table (database)" style="text-decoration: none; color: #0b0080; background-image: none; background-position: initial initial; background-repeat: initial initial; ">table</a>. This allows the client (or user) modules to be created with a higher level of&nbsp;<a href="http://en.wikipedia.org/wiki/Abstraction" title="Abstraction" style="text-decoration: none; color: #0b0080; background-image: none; background-position: initial initial; background-repeat: initial initial; ">abstraction</a>. This kind of model could be implemented by creating a class of data access methods that directly reference a corresponding set of database stored procedures. Another implementation could potentially retrieve or write records to or from a file system. The DAL hides this complexity of the underlying data store from the external world.</p><p style="margin: 0.4em 0px 0.5em; line-height: 19px; font-family: sans-serif; font-size: 13px; background-color: #ffffff; ">For example, instead of using commands such as&nbsp;<em>insert</em>,&nbsp;<em>delete</em>, and&nbsp;<em>update</em>&nbsp;to access a specific table in a database, a class and a few stored procedures could be created in the database. The procedures would be called from a method inside the class, which would return an object containing the requested values. Or, the insert, delete and update commands could be executed within simple functions like&nbsp;<em>registeruser</em>&nbsp;or&nbsp;<em>loginuser</em>&nbsp;stored within the data access layer.</p><p style="margin: 0.4em 0px 0.5em; line-height: 19px; font-family: sans-serif; font-size: 13px; background-color: #ffffff; ">Also, business logic methods from an application can be mapped to the Data Access Layer. So, for example, instead of making a query into a database to fetch all users from several tables the application can call a single method from a DAL which abstracts those database calls.</p><p style="margin: 0.4em 0px 0.5em; line-height: 19px; font-family: sans-serif; font-size: 13px; background-color: #ffffff; ">Applications using a data access layer can be either database server dependent or independent. If the data access layer supports multiple database types, the application becomes able to use whatever databases the DAL can talk to. In either circumstance, having a data access layer provides a centralized location for all calls into the database, and thus makes it easier to port the application to other database systems (assuming that 100% of the database interaction is done in the DAL for a given application).</p><p style="margin: 0.4em 0px 0.5em; line-height: 19px; font-family: sans-serif; font-size: 13px; background-color: #ffffff; "><a href="http://en.wikipedia.org/wiki/Object-Relational_Mapping" title="Object-Relational Mapping" style="text-decoration: none; color: #0b0080; background-image: none; background-position: initial initial; background-repeat: initial initial; ">Object-Relational Mapping</a>&nbsp;tools provide data layers in this fashion, following the&nbsp;<a href="http://en.wikipedia.org/wiki/Active_record_pattern" title="Active record pattern" style="text-decoration: none; color: #0b0080; background-image: none; background-position: initial initial; background-repeat: initial initial; ">active record</a>&nbsp;model. The ORM/active-record model is popular with web frameworks.</p><img src ="http://www.blogjava.net/czihong/aggbug/382970.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/czihong/" target="_blank">Chan Chen</a> 2012-07-13 06:41 <a href="http://www.blogjava.net/czihong/articles/382970.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Round Robin </title><link>http://www.blogjava.net/czihong/articles/378241.html</link><dc:creator>Chan Chen</dc:creator><author>Chan Chen</author><pubDate>Tue, 15 May 2012 18:57:00 GMT</pubDate><guid>http://www.blogjava.net/czihong/articles/378241.html</guid><wfw:comment>http://www.blogjava.net/czihong/comments/378241.html</wfw:comment><comments>http://www.blogjava.net/czihong/articles/378241.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/czihong/comments/commentRss/378241.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/czihong/services/trackbacks/378241.html</trackback:ping><description><![CDATA[<span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">轮叫调度（Round-Robin Scheduling）</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　轮叫调度（Round Robin Scheduling）算法就是以轮叫的方式依次将请求调度不同的服务器，即每次调度执行i = (i + 1) mod n，并选出第i台服务器。算法的优点是其简洁性，它无需记录当前所有连接的状态，所以它是一种无状态调度。</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　在系统实现时，我们引入了一个额外条件，当服务器的权值为零时，表示该服务器不可用而不被调度。这样做的目的是将服务器切出服务（如屏蔽服务器故障和系统维护），同时与其他加权算法保持一致。所以，算法要作相应的改动，它的算法流程如下：</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　轮叫调度算法流程</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　假设有一组服务器S = {S0, S1, &#8230;, Sn-1}，一个指示变量i表示上一次选择的</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　服务器，W(Si)表示服务器Si的权值。变量i被初始化为n-1，其中n &gt; 0。</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　j = i;</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　do {</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　j = (j + 1) mod n;</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　if (W(Sj) &gt; 0) {</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　i = j;</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　return Si;</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　}</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　} while (j != i);</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　return NULL;</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　轮叫调度算法假设所有服务器处理性能均相同，不管服务器的当前连接数和响应速度。该算法相对简单，不适用于服务器组中处理性能不一的情况，而且当请求服务时间变化比较大时，轮叫调度算法容易导致服务器间的负载不平衡。</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　虽然Round-Robin DNS方法也是以轮叫调度的方式将一个域名解析到多个IP地址，但轮叫DNS方法的调度粒度是基于每个域名服务器的，域名服务器对域名解析的缓存会妨碍轮叫解析域名生效，这会导致服务器间负载的严重不平衡。这里，IPVS轮叫调度算法的粒度是基于每个连接的，同一用户的不同连接都会被调度到不同的服务器上，所以这种细粒度的轮叫调度要比DNS的轮叫调度优越很多。</span><div style="height: 30px; line-height: 30px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><h2><span editable-title"="" data-edit-id="815587:815587:1" style="font-size: 12px; float: right; display: block; margin-top: 10px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; color: #3366cc; font-weight: normal; "><a href="http://baike.baidu.com/view/815587.htm#" style="color: #136ec2; background-image: url(http://baike.bdimg.com/static/lemma/css/img/content_icon.gif?@=3kvq7p); background-attachment: initial; background-origin: initial; background-clip: initial; background-color: initial; height: 15px; line-height: 16px; display: block; width: 52px; padding-left: 18px; background-position: -86px -573px; background-repeat: no-repeat no-repeat; ">编辑本段</a></span><a name="1" style="text-decoration: underline; color: rgb(19, 110, 194); "></a><a name="sub815587_1" style="text-decoration: underline; color: rgb(19, 110, 194); "></a>Round-robin</h2><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　</span><strong style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">RTX51 Tiny</strong><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">可以配置成使用</span><strong style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">round-robin</strong><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">多任务。Round-robin容许quasi-parallel执行多任务。任务并不是连续执行的，而是分时间片执行的（可用的CPU时间被分成时间片，RTX51 Tiny把时间片分配给各个任务）。时间片的时间很短（以毫秒为单位），所以任务看起来像连续执行一样。任务在分配给他的时间片内执行（除非放弃）。然后切换到下一个就绪的任务。这个时间片在RTX51 Tiny Configuration.配置文件中定义.</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　下面的例子是一个使用round-robin多任务的RTX51 Tiny的程序。这个程序中的两个任务都是循环计数器。RTX51 Tiny执行称为job0的任务0。这个函数创建了另一个任务job1。Job0执行完它的时间片后，RTX51 Tiny开始执行job1。Job1执行完它的时间片后，RTX51 Tiny又返回到job0开始执行。然后再切换到job1，如此循环。</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　＃include</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　int counter0;</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　int counter1;</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　void job0 (void) _task_ 0 {</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　os_create (1); /* mark task 1 as ready */</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　while (1) { /* loop forever */</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　counter0++; /* update the counter */</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　}</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　}</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　void job1 (void) _task_ 1 {</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　while (1) { /* loop forever */</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　counter1++; /* update the counter */</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　}</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　}</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　注意：除了一个任务的时片到时，也可以使用函数os_wait 或函数os_switch_task通知RTX51 Tiny可以切换到另一个任务。函数os_wait挂起当前任务直到特定的事件发生。在这期间任何其他的任务都可以执行。</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　</span><strong style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">Cooperative 任务切换</strong><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">??如果你禁止了round-robin多任务，你必须设计并执行你的任务从而让他你们以cooperativ方式工作。特别地，你必须在每个任务的某个地方调用。这些函数告知RTX51 Tiny切换到另一任务。</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　函数os_wait 和函数os_switch_task的不同之处在于os_wait可以让你的任务等待某一事件的发生，而函数os_switch_task直接切换到另一个准务就绪的任务。</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　</span><strong style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">空闲任务</strong><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　当没有任务需要运行时，RTX51 Tiny执行空闲任务。空闲任务只是一个简单的无限循环，比如：</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　SJMP $</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　有些8051器件提供了空闲模式，通过持起任务的执行以降低功耗，直到出现中断。在这种模式下，所有外围设备包括中断系统仍然在继续工作。</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　RTX51 Tiny允许你在空闲任务中初始化空闲模式（没有其他任务需要执行）。当RTX51 Tiny时钟节拍中断（或任何其他中断）出现，微控制器恢复执行程序。空闲任务执行的代码可以通过配置文件CONF_TNY.A51进行配置并使能</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　</span><strong style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">堆栈管理</strong><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　RTX51 Tiny在8051的IDATA内存区为每个任务维持一个堆栈。当一个任务执行时，给他准备了最大可能需要地堆栈。当任务切换时，前一个任务的堆栈被压栈并重定位，而把当前任务的堆栈被重定位并弹栈。STACK是堆栈的起始地址。在这个例子中，位于堆栈中的对像包括全局变量，寄存器和位地止内存，剩下的内存用作任务堆栈。内存的顶端在配置文件中定义。</span><h3><a name="1_1" style="text-decoration: underline; color: rgb(19, 110, 194); "></a><a name="sub815587_1_1" style="text-decoration: underline; color: rgb(19, 110, 194); "></a>配置RTX51 Tiny?</h3><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　RTX51 Tiny可以由根据用户的应用来定制。</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　</span><strong style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">配置</strong><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　RTX51 Tiny必须根据你的嵌入式应用来配置。所有地配置参数都在椟置文件CONF_TNY.A51中，这个文件位于\KEIL\C51\RTXTINY2\文件夹中，文件中的椟置选可以你做如下事情。</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　指定时钟节拍中断寄存器组</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　指定时钟节拍间隔（多个8051机器周期）</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　指定在时钟节拍中断中执用的用户代码</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　指定round-robin溢出时间</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　使能禁能round-robin任务切换</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　指定你的应用程序包含了长时间的中断</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　指定是否使用了code banking</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　定义RTX51 Tiny的栈顶</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　指令需要最小的堆栈空间</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　指定堆栈错误时执行代码</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　定义空闲任务操作</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　CONF_TNY.A51的默认配置包含在RTX51 Tiny的库中。然而，要在就用中使用配置文件，必须把配置文件拷贝到你的工程文件夹并添加到工程中。</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　要定制RTX51 Tiny的配置，必须改变CONF_TNY.A51的设置</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　注意：</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　如果在工程中不包括配置文件，默认的配置文件将会自动地包含到工程中。后事存在库中的配置文件可能会对你的应用起到相反效果</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　</span><strong style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">硬件时钟</strong><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　以下参数指定了如何配置制RTX51 Tiny的配件时钟</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　INT_REGBANK 指定制RTX51 Tiny时钟中断使用的寄存器组，默认的是寄存器组1</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　INT_CLOCK 指定时钟产生中断前的周期数据。这个值的范围是1000~65535。较小的值产生中断较快。这个值用来计算时钟的重新装载值（65536-INT_CLOCK）。缺省值是10000。</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　HW_TIMER_CODE 是一个宏定义，它用来指定在制RTX51 Tiny时钟节拍中断中执的代码。这个宏缺省的设置是从中断中返回（RETI）如：</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　HW_TIMER_CODE MACRO</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　; Empty Macro by default</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　RETI</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　ENDM</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　</span><strong style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">Round-robin</strong><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　Round-robin切换是默认使能的，以下参数用来设定Round-robin切换的时间或禁能Round-robin切换</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　TIMESHARING 指定任务在进行Round-robin切换前执行的RTX51 Tiny时钟节拍数。当这个值为0时禁止Round-robin切换。缺省值是5个时钟节拍。</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　</span><strong style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">长时间中断</strong><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　一般情况下，中断服务程序（ISRs）都要求很快执行完毕。有时候，中断服务程序可能需执行很长一段时间。如果一个高优先级的中断执的时间超过了节拍间隔，RTX51的时钟中断就可能被这个更高优先级的中断中断了，并且被以后的RTX51 时钟中断重入了。</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　如果使用了需要运行很长时间的高优先级中断，就应该考虑减少中断服务程序的工作量，改变RTX51 时钟节拍的速率，或考使用以下配置。</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　LONG_USR_ISR 指定是否使用执行时间超过时钟节拍的中断。当这个值置为1时，RTX51 Tiny就会把保护RTX51 Tiny时钟节拍中断重入的代码包含进去。这个值缺省为0</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　</span><strong style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">Code banking</strong><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　以下设置指定RTX51 Tiny应用中是否使用code banking</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　CODE_BANKING 置1使用code banking，清0不使用code banking。缺省值为0</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　注意：L51_BANK.A51的2.2或更高版本需要RTX51 Tiny 程序使用code banking</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　</span><strong style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">堆栈</strong><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　堆栈的配置选项有几个。以下参指定了用于堆栈的内存空间的大小和堆栈的最小空间。当CPU的堆栈空间不够时用一个宏指定去执行哪一段代码。</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　RAMTOP指定栈顶地址。最好不要修改这个地址除非你在这个堆栈的上面使用了IDATA变量。</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　FREE_STACK指定堆栈上的最少可用空间。当切换到一个任务是时，如果RTX51 Tiny检测到可用的堆栈空间小于这个值，STACK_ERROR宏就会被执行。置为0将禁止对堆栈的检查，缺省值为20字节</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　STACK_ERROR是一个宏，它代表了一段在堆栈出现错误时执行的代码。这个宏的缺省代码为禁能中断并进入一个无限循环。如</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　STACK_ERROR MACRO</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　CLR EA ; disable interrupts</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　SJMP $ ; endless loop if stack space is exhausted</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　ENDM</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　</span><strong style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">空闲任务</strong><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　没有任务需要执行时，RTX51 Tiny就执行空闲任务。空闲任务什么都不做，只是等待RTX51 Tiny的时钟节拍中断并切换到另一个就绪的任务。以下参数用来配置RTX51 Tiny空闲任务的不同方面</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　CPU_IDLE 这是一个宏，代表了在空闲任务中执行的代码。缺省指令是设置寄存器PCON的空闲模式位。这样就可以通过挂起程序节省能耗。如</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　CPU_IDLE MACRO</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　ORL PCON,#1 ; set 8051 CPU to IDLE</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　ENDM</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　CPU_IDLE_CODE 指定CPU_IDLE宏在空闲任务中是否执行。缺省值为0，这样空闲任务将不包含CPU_IDLE宏</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　</span><strong style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">库文件</strong><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　RTX51 Tiny包括两个库文件</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　RTX51TNY.LIB is used for non-banking RTX51 Tiny programs</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　RTX51BT.LIB is used for code-banking RTX51 Tiny programs.</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　The RTXTINY2.PRJ project found in the \KEIL\C51\RTXTINY2\SOURCECODE\ folder is used to build these two libraries.</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　注意：不需要在应用显式地包含这两个文件。如果你使用&#956;Vision2 IDE或command-line linker时这两个文件会自动地包含进去。</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　如果要建立RTX51 Tiny的库，缺省的配置文件会加入进去。如果不显式地声明包含配置文件，默认的配置文件会包含进去。以后对配置文件做的修改会对就用产生意想不到的效果。</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　</span><strong style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">优化</strong><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　可以通过以下方式优化RTX51 Tiny程序</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　如果可能，禁能round-robin任务切换。Round-robin需要13字节堆栈空间来存储任务地址和所有寄存器。如果任务切换是通过RTX51 Tiny运行时库（比如os_wait或 os_switch_task）来触发的就不需要这些空间了。</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　使用os_wait而不是使用round-robin的时间耗尽来切换任务。这些会提高系统的反应时间和任务的反应速度</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　避免把系统时钟节拍的中断速率设的太高。把时钟溢出的时间设的比较短增加了每秒的时钟节拍数但是减少了每个任的可用时间，因为每个时钟节拍中断会使用100-200个周期来运行。所以要把湔出时间设的足够的小从而减小时钟节拍中断带来的副作用。</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　使用RTX51 Tiny</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　要使用RTX51 Tiny，必须成功地生成RTX51程序并编译连接他们</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　</span><strong style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">编写程序</strong><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　定义RTX51程序使用关键字 _task_</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　以RTX51TNY.H的模板使用RTX51 Tiny的内核</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　包含文件</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　RTX51 Tiny只需包含一个文件RTX51TNY.H。所有的运行时库来常量都在这个头文件中定义。可以采用以下方式包含它：</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　＃include &lt;rtx51tny.h&gt;</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　</span><strong style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">编程指南</strong><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　使用RTX51 Tiny编程时须遵循下规则：</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　包含文件rtx51tny.h</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　不要创建C主函数，RTX51 Tiny有它自已的主要函数</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　程序至少创建一个任务</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　程序必须至少调用一次RTX51 Tiny运行时库（如os_wait）。否则，连接器将不会把RTX51 Tiny库包含进去</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　任务0是你的程序执行的第一任务。必须调用在任务0中调用os_create_task函数来运行其他任务</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　任务永不返回或退出。任务必须使用while(1)或类似的结构。使用os_delete_task函数可以挂起一个任务</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　必须在&#956;Vision2中或在连接编译命令行中指定RTX51 Tiny</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　</span><strong style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">定义任务</strong><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　实时或多任务应用由一个或多个完成特定功能的任务组成。RTX51 Tiny支持最多16个任务</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　任务必须是用_task_声明的C函数，返回值和参数都必须是void类型的，如</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　void func (void) _task_ task_id</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　这里</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　func is the name of the task function.</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　task_id is a task ID number from 0 to 15</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　以下例子定义了函数job0作为一个任务，任务编号为0。</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　void job0 (void) _task_ 0 {</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　while (1) {</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　counter0++; /* increment counter */</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　}</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　}</span><div style="height: 14px; line-height: 14px; font-size: 12px; overflow-x: hidden; overflow-y: hidden; font-family: arial, 宋体, sans-serif; background-color: #ffffff; "></div><span style="font-family: arial, 宋体, sans-serif; line-height: 24px; background-color: #ffffff; ">　　注意：所有的任务都必须通过循环实现，而且永不返回</span>&nbsp;<img src ="http://www.blogjava.net/czihong/aggbug/378241.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/czihong/" target="_blank">Chan Chen</a> 2012-05-16 02:57 <a href="http://www.blogjava.net/czihong/articles/378241.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>memcached协议</title><link>http://www.blogjava.net/czihong/articles/373216.html</link><dc:creator>Chan Chen</dc:creator><author>Chan Chen</author><pubDate>Sun, 01 Apr 2012 11:21:00 GMT</pubDate><guid>http://www.blogjava.net/czihong/articles/373216.html</guid><wfw:comment>http://www.blogjava.net/czihong/comments/373216.html</wfw:comment><comments>http://www.blogjava.net/czihong/articles/373216.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/czihong/comments/commentRss/373216.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/czihong/services/trackbacks/373216.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 在memcache协议中发送的数据分两种：文本行 和 自由数据。 文本行被用于来自客户端的命令和服务器的回应。自由数据用于客户端从服务器端存取数据时。存储在memcached中的数据通过键值来标识。键值是一个文本字符串，对于需要存取这项数据的客户端而言，它必须是唯一的。协议Protocolmemcached 的客户端使用TCP链接 与 服务器通讯。（UDP接口也同样有效，参考后文的 &#8220;...&nbsp;&nbsp;<a href='http://www.blogjava.net/czihong/articles/373216.html'>阅读全文</a><img src ="http://www.blogjava.net/czihong/aggbug/373216.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/czihong/" target="_blank">Chan Chen</a> 2012-04-01 19:21 <a href="http://www.blogjava.net/czihong/articles/373216.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>RESTful HTTP的实践</title><link>http://www.blogjava.net/czihong/articles/373215.html</link><dc:creator>Chan Chen</dc:creator><author>Chan Chen</author><pubDate>Sun, 01 Apr 2012 10:56:00 GMT</pubDate><guid>http://www.blogjava.net/czihong/articles/373215.html</guid><wfw:comment>http://www.blogjava.net/czihong/comments/373215.html</wfw:comment><comments>http://www.blogjava.net/czihong/articles/373215.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/czihong/comments/commentRss/373215.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/czihong/services/trackbacks/373215.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 本文对RESTful HTTP的基础原理做了一个概览，探讨了开发者在设计RESTful HTTP应用时所面临的典型问题，展示了如何在实践中应用REST架构风格，描述了常用的URI命名方法，讨论了如何使用统一接口进行资源交互，何时使用PUT或POST以及如何支持非CURD操作等。虽然REST受Web技术的影响很深，但是理论上REST架构风格并非绑定在HTTP上。然而，HTTP是唯一与REST相关的实...&nbsp;&nbsp;<a href='http://www.blogjava.net/czihong/articles/373215.html'>阅读全文</a><img src ="http://www.blogjava.net/czihong/aggbug/373215.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/czihong/" target="_blank">Chan Chen</a> 2012-04-01 18:56 <a href="http://www.blogjava.net/czihong/articles/373215.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>SOAP Webservice和RESTful Webservice</title><link>http://www.blogjava.net/czihong/articles/370774.html</link><dc:creator>Chan Chen</dc:creator><author>Chan Chen</author><pubDate>Sat, 25 Feb 2012 09:21:00 GMT</pubDate><guid>http://www.blogjava.net/czihong/articles/370774.html</guid><wfw:comment>http://www.blogjava.net/czihong/comments/370774.html</wfw:comment><comments>http://www.blogjava.net/czihong/articles/370774.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/czihong/comments/commentRss/370774.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/czihong/services/trackbacks/370774.html</trackback:ping><description><![CDATA[<div style="text-align: left;">Refer to:<font color="#494949" face="simsun">&nbsp;</font><a href="http://blog.sina.com.cn/s/blog_493a845501012566.html">http://blog.sina.com.cn/s/blog_493a845501012566.html</a></div> <span style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; "><br />REST是一种架构风格，其核心是面向资源，REST专门针对网络应用设计和开发方式，以降低开发的复杂性，提高系统的可伸缩性。REST提出设计概念和准则为：</span><br style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; " /><br style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; " /><span style="color: #494949; font-family: simsun; text-align: left; background-color: yellow; ">1.网络上的</span><span style="word-wrap: normal; word-break: normal; color: #494949; font-family: simsun; text-align: left; font-weight: bold; background-color: yellow; ">所有事物都可以被抽象为资源(resource)</span><br style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; " /><span style="color: #494949; font-family: simsun; text-align: left; background-color: yellow; ">2.每一个资源都有唯一的资源标识(resource identifier)，对资源的操作不会改变这些标识</span><br style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; " /><span style="color: #494949; font-family: simsun; text-align: left; background-color: yellow; ">3.所有的操作都是</span><span style="word-wrap: normal; word-break: normal; color: #494949; font-family: simsun; text-align: left; font-weight: bold; background-color: yellow; ">无状态</span><span style="color: #494949; font-family: simsun; text-align: left; background-color: yellow; ">的</span><br style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; " /><br style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; " /><span style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; ">REST简化开发，</span><span style="color: #494949; font-family: simsun; text-align: left; background-color: yellow; ">其架构遵循CRUD原则，该原则告诉我们对于资源(包括网络资源)只需要四种行为：创建，获取，更新和删除就可以完成相关的操作和处理</span><span style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; ">。您可以通过统一资源标识符（Universal Resource Identifier，URI）来识别和定位资源，并且针对这些资源而执行的操作是通过 HTTP 规范定义的。</span><span style="word-wrap: normal; word-break: normal; color: #494949; font-family: simsun; text-align: left; font-weight: bold; background-color: yellow; ">其核心操作只有GET,PUT,POST,DELETE。</span><br style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; " /><br style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; " /><span style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; ">由于REST强制所有的操作都必须是stateless的，这就没有上下文的约束，如果做分布式，集群都不需要考虑上下文和会话保持的问题。极大的提高系统的可伸缩性。</span><br style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; " /><br style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; " /><span style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; ">对于SOAP Webservice和Restful Webservice的选择问题，首先需要理解就是</span><span style="color: #494949; font-family: simsun; text-align: left; background-color: yellow; ">SOAP偏向于面向活动，有严格的规范和标准，包括安全，事务等各个方面的内容，同时SOAP强调操作方法和操作对象的分离，有WSDL文件规范和XSD文件分别对其定义</span><span style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; ">。而REST强调面向资源，只要我们要操作的对象可以抽象为资源即可以使用REST架构风格。</span><br style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; " /><br style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; " /><span style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; ">如果从这个意义上讲，是否使用REST就需要考虑资源本身的抽象和识别是否困难，如果本身就是简单的类似增删改查的业务操作，那么抽象资源就比较容易，</span><span style="color: #494949; font-family: simsun; text-align: left; background-color: yellow; ">而对于复杂的业务活动抽象资源并不是一个简单的事情。比如校验用户等级，转账，事务处理等，这些往往并不容易简单的抽象为资源。</span><br style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; " /><br style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; " /><span style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; ">其次如果有严格的规范和标准定义要求，而且前期规范标准需要指导多个业务系统集成和开发的时候，SOAP风格由于有清晰的规范标准定义是明显有优势的。我们可以在开始和实现之前就严格定义相关的接口方法和接口传输数据。</span><br style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; " /><br style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; " /><span style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; ">简单数据操作，无事务处理，开发和调用简单这些是使用REST架构风格的优势。而对于较为复杂的面向活动的服务，如果我们还是使用REST，很多时候都是仍然是传统的面向活动的思想通过转换工具再转换得到REST服务，这种使用方式是没有意义的。</span><br style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; " /><br style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; " /><span style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; ">正如另外一篇文章里面谈到的，</span><span style="color: #494949; font-family: simsun; text-align: left; background-color: yellow; ">REST核心是url和面向资源，url代替了原来复杂的操作方法</span><span style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; ">。REST允许我们通过url设计系统，就像测试驱动开发使用测试用例设计类接口一样。所有可以被抽象为资源的东西都可以使用RESTful的url，当我们以传统的用SOAP方式实现的一个查询订单服务的时候可以看到，这个服务首先存在输入的查询条件，然后才是输出结果集。那么对于类似场景要使用REST，</span><span style="word-wrap: normal; word-break: normal; color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; font-weight: bold; ">不可避免的会将传统的SOAP服务拆分为一个HTTP POST操作和一个HTTP GET操作。前面是输入，而后面是输出。</span><br style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; " /><br style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; " /><span style="word-wrap: normal; word-break: normal; color: #494949; font-family: simsun; text-align: left; font-weight: bold; background-color: yellow; ">使用REST的关键是如何抽象资源，抽象的越精确，对REST的应用越好</span><span style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; ">。如何进行抽象，面向资源的设计和传统的面向结构和对象设计区别，资源和对象，数据库表之间的差别是另外一个在分析设计时候要考虑的问题。在REST分析设计中如何改变传统的SOAP分析设计思想又是一个重要问题。</span><br style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; " /><br style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; " /><span style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; ">下文转载自：</span><a href="http://hi.baidu.com/gaohong230/blog/item/cd3924396bc7332fb9998f52.html" target="_blank" style="text-decoration: none; color: #6a6352; font-family: simsun; text-align: left; background-color: #e2ddc7; ">http://hi.baidu.com/gaohong230/blog/item/cd3924396bc7332fb9998f52<wbr>.html</a><br style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; " /><br style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; " /><span style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; ">在SOA的基础技术实现方式中WebService占据了很重要的地位，通常我们提到WebService第一想法就是SOAP消息在各种传输协议上交互。近几年REST的思想伴随着SOA逐渐被大家接受，同时各大网站不断开放API提供给开发者，也激起了REST风格WebService的热潮。</span><br style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; " /><br style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; " /><span style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; ">SOAP</span><br style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; " /><br style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; " /><span style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; ">什么是SOAP，我想不用多说，google一把满眼都是。其实SOAP最早是针对RPC的一种解决方案，简单对象访问协议，很轻量，同时作为应用协议可以基于多种传输协议来传递消息（Http,SMTP等）。但是随着SOAP作为WebService的广泛应用，不断地增加附加的内容，使得现在开发人员觉得SOAP很重，使用门槛很高。在SOAP后续的发展过程中，WS-*一系列协议的制定，增加了SOAP的成熟度，也给SOAP增加了负担。</span><br style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; " /><br style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; " /><span style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; ">REST</span><br style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; " /><br style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; " /><span style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; ">REST其实并不是什么协议也不是什么标准，而是将Http协议的设计初衷作了诠释，在Http协议被广泛利用的今天，越来越多的是将其作为传输协议，而非原先设计者所考虑的应用协议。SOAP类型的WebService就是最好的例子，SOAP消息完全就是将Http协议作为消息承载，以至于对于Http协议中的各种参数（例如编码，错误码等）都置之不顾。其实，最轻量级的应用协议就是Http协议。Http协议所抽象的get,post,put,delete就好比数据库中最基本的增删改查，而互联网上的各种资源就好比数据库中的记录（可能这么比喻不是很好），对于各种资源的操作最后总是能抽象成为这四种基本操作，在定义了定位资源的规则以后，对于资源的操作通过标准的Http协议就可以实现，开发者也会受益于这种轻量级的协议。</span><br style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; " /><br style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; " /><span style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; ">REST的思想归结以下有如下几个关键点：</span><br style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; " /><br style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; " /><span style="color: #494949; font-family: simsun; text-align: left; background-color: yellow; ">1．面向资源的接口设计</span><br style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; " /><br style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; " /><span style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; ">所有的接口设计都是针对资源来设计的，也就很类似于我们的面向对象和面向过程的设计区别，只不过现在将网络上的操作实体都作为资源来看待，同时URI的设计也是体现了对于资源的定位设计。后面会提到有一些网站的API设计说是REST设计，其实是RPC-REST的混合体，并非是REST的思想。</span><br style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; " /><br style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; " /><span style="color: #494949; font-family: simsun; text-align: left; background-color: yellow; ">2．抽象操作为基础的CRUD</span><br style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; " /><br style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; " /><span style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; ">这点很简单，Http中的get,put,post,delete分别对应了read,update,create,delete四种操作，如果仅仅是作为对于资源的操作，抽象成为这四种已经足够了，但是对于现在的一些复杂的业务服务接口设计，可能这样的抽象未必能够满足。其实这也在后面的几个网站的API设计中暴露了这样的问题，如果要完全按照REST的思想来设计，那么适用的环境将会有限制，而非放之四海皆准的。&nbsp;</span><wbr style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; ">&nbsp;<wbr style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; ">&nbsp;<wbr style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; ">&nbsp;<wbr style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; "><span style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; ">&nbsp;&nbsp;</span><wbr style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; "><br style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; " /><br style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; " /><span style="color: #494949; font-family: simsun; text-align: left; background-color: yellow; ">3．Http是应用协议而非传输协议</span><br style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; " /><br style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; " /><span style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; ">这点在后面各大网站的API分析中有很明显的体现，其实有些网站已经走到了SOAP的老路上，说是REST的理念设计，其实是作了一套私有的SOAP协议，因此称之为REST风格的自定义SOAP协议。</span><br style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; " /><br style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; " /><span style="color: #494949; font-family: simsun; text-align: left; background-color: yellow; ">4．无状态，自包含</span><br style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; " /><br style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; " /><span style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; ">这点其实不仅仅是对于REST来说的，作为接口设计都需要能够做到这点，也是作为可扩展和高效性的最基本的保证，就算是使用SOAP的WebService也是一样。</span><br style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; " /><br style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; " /><span style="word-wrap: normal; word-break: normal; color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; font-weight: bold; ">SOAP Webservice和RESTful Webservice的比较</span><br style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; " /><br style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; " /><span style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; ">成熟度(总的来说SOAP在成熟度上优于REST)</span><br style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; " /><br style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; " /><span style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; ">SOAP虽然发展到现在已经脱离了初衷，但是对于异构环境服务发布和调用，以及厂商的支持都已经达到了较为成熟的情况。不同平台，开发语言之间通过SOAP来交互的web service都能够较好的互通（在部分复杂和特殊的参数和返回对象解析上，协议没有作很细致的规定，导致还是需要作部分修正）</span><br style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; " /><br style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; " /><span style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; ">REST国外很多大网站都发布了自己的开发API，很多都提供了SOAP和REST两种Web Service，根据调查部分网站的REST风格的使用情况要高于SOAP。但是由于REST只是一种基于Http协议实现资源操作的思想，因此各个网站的REST实现都自有一套，在后面会讲诉各个大网站的REST API的风格。也正是因为这种各自实现的情况，在性能和可用性上会大大高于SOAP发布的web service，但统一通用方面远远不及SOAP。由于这些大网站的SP往往专注于此网站的API开发，因此通用性要求不高。</span><br style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; " /><br style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; " /><span style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; ">由于没有类似于SOAP的权威性协议作为规范，REST实现的各种协议仅仅只能算是私有协议，当然需要遵循REST的思想，但是这样细节方面有太多没有约束的地方。REST日后的发展所走向规范也会直接影响到这部分的设计是否能够有很好的生命力。</span><br style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; " /><br style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; " /><span style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; ">效率和易用性(REST更胜一筹)</span><br style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; " /><br style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; " /><span style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; ">SOAP协议对于消息体和消息头都有定义，同时消息头的可扩展性为各种互联网的标准提供了扩展的基础，WS-*系列就是较为成功的规范。但是也由于SOAP由于各种需求不断扩充其本身协议的内容，导致在SOAP处理方面的性能有所下降。同时在易用性方面以及学习成本上也有所增加。</span><br style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; " /><br style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; " /><span style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; ">REST被人们的重视，其实很大一方面也是因为其高效以及简洁易用的特性。这种高效一方面源于其面向资源接口设计以及操作抽象简化了开发者的不良设计，同时也最大限度的利用了Http最初的应用协议设计理念。同时，在我看来REST还有一个很吸引开发者的就是能够很好的融合当前Web2.0的很多前端技术来提高开发效率。例如很多大型网站开放的REST风格的API都会有多种返回形式，除了传统的xml作为数据承载，还有（JSON,RSS,ATOM）等形式，这对很多网站前端开发人员来说就能够很好的mashup各种资源信息。</span><br style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; " /><br style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; " /><span style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; ">安全性：</span><br style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; " /><br style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; " /><span style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; ">这点其实可以放入到成熟度中，不过在当前的互联网应用和平台开发设计过程中，安全已经被提到了很高的高度，特别是作为外部接口给第三方调用，安全性可能会高过业务逻辑本身。</span><br style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; " /><br style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; " /><span style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; ">SOAP在安全方面是通过使用XML-Security和XML-Signature两个规范组成了WS-Security来实现安全控制的，当前已经得到了各个厂商的支持，.net ，php ，java 都已经对其有了很好的支持（虽然在一些细节上还是有不兼容的问题，但是互通基本上是可以的）。</span><br style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; " /><br style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; " /><span style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; ">REST没有任何规范对于安全方面作说明，同时现在开放REST风格API的网站主要分成两种，一种是自定义了安全信息封装在消息中（其实这和SOAP没有什么区别），另外一种就是靠硬件SSL来保障,但是这只能够保证点到点的安全，如果是需要多点传输的话SSL就无能为力了。安全这块其实也是一个很大的问题，今年在BEA峰会上看到有演示采用SAML2实现的网站间SSO，其实是直接采用了XML-Security和XML-Signature，效率看起来也不是很高。未来REST规范化和通用化过程中的安全是否也会采用这两种规范，是未知的，但是加入的越多，REST失去它高效性的优势越多。</span><br style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; " /><br style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; " /><span style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; ">应用设计与改造：</span><br style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; " /><br style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; " /><span style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; ">我们的系统要么就是已经有了那些需要被发布出去的服务，要么就是刚刚设计好的服务，但是开发人员的传统设计思想让REST的形式被接受还需要一点时间。同时在资源型数据服务接口设计上来说按照REST的思想来设计相对来说要容易一些，而对于一些复杂的服务接口来说，可能强要去按照REST的风格来设计会有些牵强。这一点其实可以看看各大网站的接口就可以知道，很多网站还要传入function的名称作为参数，这就明显已经违背了REST本身的设计思路。而SOAP本身就是面向RPC来设计的，开发人员十分容易接受，所以不存在什么适应的过程。总的来说，其实还是一个老观念，适合的才是最好的</span><br style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; " /><br style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; " /><span style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; ">技术没有好坏，只有是不是合适，一种好的技术和思想被误用了，那么就会得到反效果。REST和SOAP各自都有自己的优点，同时如果在一些场景下如果去改造REST，其实就会走向SOAP（例如安全）。</span><br style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; " /><br style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; " /><span style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; ">REST对于资源型服务接口来说很合适，同时特别适合对于效率要求很高，但是对于安全要求不高的场景。而SOAP的成熟性可以给需要提供给多开发语言的，对于安全性要求较高的接口设计带来便利。所以我觉得纯粹说什么设计模式将会占据主导地位没有什么意义，关键还是看应用场景。</span><br style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; " /><br style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; " /><span style="color: #494949; font-family: simsun; text-align: left; background-color: #e2ddc7; ">同时很重要一点就是不要扭曲了REST现在很多网站都跟风去开发REST风格的接口，其实都是在学其形，不知其心，最后弄得不伦不类，性能上不去，安全又保证不了，徒有一个看似象摸象样的皮囊。</span><img src ="http://www.blogjava.net/czihong/aggbug/370774.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/czihong/" target="_blank">Chan Chen</a> 2012-02-25 17:21 <a href="http://www.blogjava.net/czihong/articles/370774.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>编译器工作原理</title><link>http://www.blogjava.net/czihong/articles/370624.html</link><dc:creator>Chan Chen</dc:creator><author>Chan Chen</author><pubDate>Thu, 23 Feb 2012 14:25:00 GMT</pubDate><guid>http://www.blogjava.net/czihong/articles/370624.html</guid><wfw:comment>http://www.blogjava.net/czihong/comments/370624.html</wfw:comment><comments>http://www.blogjava.net/czihong/articles/370624.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/czihong/comments/commentRss/370624.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/czihong/services/trackbacks/370624.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 编译器，是将便于人编写，阅读，维护的高级计算机语言翻译为计算机能识别，运行的低级机器语言的程序。编译器将源程序（Source program）作为输入，翻译产生使用目标语言（Target language）的等价程序。源程序一般为高级语言（High-level language），如Pascal，C++等，而目标语言则是汇编语言或目标机器的目标代码（Object code），有时也称作机器代码（M...&nbsp;&nbsp;<a href='http://www.blogjava.net/czihong/articles/370624.html'>阅读全文</a><img src ="http://www.blogjava.net/czihong/aggbug/370624.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/czihong/" target="_blank">Chan Chen</a> 2012-02-23 22:25 <a href="http://www.blogjava.net/czihong/articles/370624.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>什么是REST</title><link>http://www.blogjava.net/czihong/articles/370515.html</link><dc:creator>Chan Chen</dc:creator><author>Chan Chen</author><pubDate>Wed, 22 Feb 2012 05:21:00 GMT</pubDate><guid>http://www.blogjava.net/czihong/articles/370515.html</guid><wfw:comment>http://www.blogjava.net/czihong/comments/370515.html</wfw:comment><comments>http://www.blogjava.net/czihong/articles/370515.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/czihong/comments/commentRss/370515.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/czihong/services/trackbacks/370515.html</trackback:ping><description><![CDATA[<p style="margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: #333333; background-color: #f8f8f8; text-indent: 28px; font-family: 宋体; line-height: 28px; "><strong style="font-weight: bold; text-align: center; ">什么是REST？</strong></p><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: #333333; background-color: #f8f8f8; text-indent: 28px; font-family: 宋体; line-height: 28px; ">REST (REpresentation State Transfer) 描述了一个架构样式的网络系统，比如 web 应用程序。它首次出现在 2000 年 Roy Fielding 的博士论文中，他是 HTTP 规范的主要编写者之一。<strong style="font-weight: bold; text-align: center; background-color: yellow; ">REST 指的是一组架构约束条件和原则。</strong><span style="background-color: yellow; ">满足这些约束条件和原则的应用程序或设计就是 RESTful。</span></p><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: #333333; background-color: #f8f8f8; text-indent: 28px; font-family: 宋体; line-height: 28px; ">Web 应用程序最重要的 REST 原则是，<span style="background-color: yellow; ">客户端和服务器之间的交互在请求之间是无状态的</span>。<span style="background-color: yellow; ">从客户端到服务器的每个请求都必须包含理解请求所必需的信息</span>。如果服务器在请求之间的任何时间点重启，客户端不会得到通知。<span style="background-color: yellow; ">此外，无状态请求可以由任何可用服务器回答，这十分适合云计算之类的环境。客户端可以缓存数据以改进性能。</span></p><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: #333333; background-color: #f8f8f8; text-indent: 28px; font-family: 宋体; line-height: 28px; ">在服务器端，应用程序状态和功能可以分为各种资源。资源是一个有趣的概念实体，它向客户端公开。资源的例子有：<span style="background-color: yellow; ">应用程序对象、数据库记录、算法等等</span>。<span style="background-color: yellow; ">每个资源都使用 URI (Universal Resource Identifier) 得到一个惟一的地址</span>。所有资源都共享统一的界面，以便在客户端和服务器之间传输状态。使用的是标准的 HTTP 方法，比如 GET、PUT、POST 和 DELETE。Hypermedia 是应用程序状态的引擎，资源表示通过超链接互联。</p><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: #333333; background-color: #f8f8f8; text-indent: 28px; font-family: 宋体; line-height: 28px; "><strong style="font-weight: bold; text-align: center; background-color: yellow; ">另一个重要的 REST 原则是分层系统</strong><span style="background-color: yellow; ">，这表示组件无法了解它与之交互的中间层以外的组件。通过将系统知识限制在单个层，可以限制整个系统的复杂性，促进了底层的独立性。</span></p><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: #333333; background-color: #f8f8f8; text-indent: 28px; font-family: 宋体; line-height: 28px; ">当 REST 架构的约束条件作为一个整体应用时，将生成一个可以扩展到大量客户端的应用程序。它还降低了客户端和服务器之间的交互延迟。统一界面简化了整个系统架构，改进了子系统之间交互的可见性。<strong style="font-weight: bold; text-align: center; ">REST 简化了客户端和服务器的实现。</strong></p><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: #333333; background-color: #f8f8f8; text-indent: 28px; font-family: 宋体; line-height: 28px; "><strong style="font-weight: bold; text-align: center; ">RESTful的实现：RESTful Web 服务与 RPC 样式的 Web 服务</strong></p><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: #333333; background-color: #f8f8f8; text-indent: 28px; font-family: 宋体; line-height: 28px; ">了解了什么是什么是REST，我们再看看RESTful的实现。最近，使用 RPC 样式架构构建的基于 SOAP 的 Web 服务成为实现 SOA 最常用的方法。RPC 样式的 Web 服务客户端将一个装满数据的信封（包括方法和参数信息）通过 HTTP 发送到服务器。服务器打开信封并使用传入参数执行指定的方法。方法的结果打包到一个信封并作为响应发回客户端。客户端收到响应并打开信封。<span style="background-color: yellow; ">每个对象都有自己独特的方法以及仅公开一个 URI 的 RPC 样式 Web 服务，URI 表示单个端点。它忽略 HTTP 的大部分特性且仅支持 POST 方法。</span></p><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: #333333; background-color: #f8f8f8; text-indent: 28px; font-family: 宋体; line-height: 28px; ">由于轻量级以及通过 HTTP 直接传输数据的特性，Web 服务的 RESTful 方法已经成为最常见的替代方法。可以使用各种语言（比如 Java 程序、Perl、Ruby、Python、PHP 和 Javascript[包括 Ajax]）实现客户端。RESTful Web 服务通常可以通过自动客户端或代表用户的应用程序访问。但是，这种服务的简便性让用户能够与之直接交互，使用它们的 Web 浏览器构建一个 GET URL 并读取返回的内容。</p><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: #333333; background-color: #f8f8f8; text-indent: 28px; font-family: 宋体; line-height: 28px; "><span style="background-color: yellow; ">在 REST 样式的 Web 服务中，每个资源都有一个地址。资源本身都是方法调用的目标，方法列表对所有资源都是一样的。这些方法都是标准方法，包括 HTTP GET、POST、PUT、DELETE，还可能包括 HEADER 和 OPTIONS。</span></p><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: #333333; background-color: #f8f8f8; text-indent: 28px; font-family: 宋体; line-height: 28px; ">在 RPC 样式的架构中，关注点在于方法，而在 REST 样式的架构中，关注点在于资源 &#8212;&#8212; 将使用标准方法检索并操作信息片段（使用表示的形式）。资源表示形式在表示形式中使用超链接互联。</p><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: #333333; background-color: #f8f8f8; text-indent: 28px; font-family: 宋体; line-height: 28px; ">Leonard Richardson 和 Sam Ruby 在他们的著作 RESTful Web Services 中引入了术语 REST-RPC 混合架构。REST-RPC 混合 Web 服务不使用信封包装方法、参数和数据，而是直接通过 HTTP 传输数据，这与 REST 样式的 Web 服务是类似的。但是它不使用标准的 HTTP 方法操作资源。它在 HTTP 请求的 URI 部分存储方法信息。好几个知名的 Web 服务，比如 Yahoo 的 Flickr API 和 del.icio.us API 都使用这种混合架构。</p><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: #333333; background-color: #f8f8f8; text-indent: 28px; font-family: 宋体; line-height: 28px; "><strong style="font-weight: bold; text-align: center; ">RESTful的实现：RESTful Web 服务的 Java 框架</strong></p><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: #333333; background-color: #f8f8f8; text-indent: 28px; font-family: 宋体; line-height: 28px; ">有两个 Java 框架可以帮助构建 RESTful Web 服务。erome Louvel 和 Dave Pawson 开发的 Restlet（见 参考资料）是轻量级的。它实现针对各种 RESTful 系统的资源、表示、连接器和媒体类型之类的概念，包括 Web 服务。在 Restlet 框架中，客户端和服务器都是组件。组件通过连接器互相通信。该框架最重要的类是抽象类 Uniform 及其具体的子类 Restlet，该类的子类是专用类，比如 Application、Filter、Finder、Router 和 Route。这些子类能够一起处理验证、过滤、安全、数据转换以及将传入请求路由到相应资源等操作。Resource 类生成客户端的表示形式。</p><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: #333333; background-color: #f8f8f8; text-indent: 28px; font-family: 宋体; line-height: 28px; ">JSR-311是 Sun Microsystems 的规范，可以为开发 RESTful Web 服务定义一组 Java API。Jersey是对 JSR-311 的参考实现。</p><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: #333333; background-color: #f8f8f8; text-indent: 28px; font-family: 宋体; line-height: 28px; ">JSR-311 提供一组注释，相关类和接口都可以用来将 Java 对象作为 Web 资源展示。该规范假定 HTTP 是底层网络协议。它使用注释提供 URI 和相应资源类之间的清晰映射，以及 HTTP 方法与 Java 对象方法之间的映射。API 支持广泛的 HTTP 实体内容类型，包括 HTML、XML、JSON、GIF、JPG 等。它还将提供所需的插件功能，以允许使用标准方法通过应用程序添加其他类型。</p><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: #333333; background-color: #f8f8f8; text-indent: 28px; font-family: 宋体; line-height: 28px; "><strong style="font-weight: bold; text-align: center; ">RESTful的实现：构建 RESTful Web 服务的多层架构</strong></p><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: #333333; background-color: #f8f8f8; text-indent: 28px; font-family: 宋体; line-height: 28px; ">RESTful Web 服务和动态 Web 应用程序在许多方面都是类似的。有时它们提供相同或非常类似的数据和函数，尽管客户端的种类不同。例如，在线电子商务分类网站为用户提供一个浏览器界面，用于搜索、查看和订购产品。如果还提供 Web 服务供公司、零售商甚至个人能够自动订购产品，它将非常有用。与大部分动态 Web 应用程序一样，Web 服务可以从多层架构的关注点分离中受益。业务逻辑和数据可以由自动客户端和 GUI 客户端共享。惟一的不同点在于客户端的本质和中间层的表示层。此外，从数据访问中分离业务逻辑可实现数据库独立性，并为各种类型的数据存储提供插件能力。</p><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: #333333; background-color: #f8f8f8; text-indent: 28px; font-family: 宋体; line-height: 28px; ">图 1 展示了自动化客户端，包括 Java 和各种语言编写的脚本，这些语言包括 Python、Perl、Ruby、PHP 或命令行工具，比如 curl。在浏览器中运行且作为 RESTful Web 服务消费者运行的 Ajax、Flash、JavaFX、GWT、博客和 wiki 都属于此列，因为它们都代表用户以自动化样式运行。自动化 Web 服务客户端在 Web 层向 Resource Request Handler 发送 HTTP 响应。客户端的无状态请求在头部包含方法信息，即 POST、GET、PUT 和 DELETE，这又将映射到 Resource Request Handler 中资源的相应操作。每个请求都包含所有必需的信息，包括 Resource Request Handler 用来处理请求的凭据。</p><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: #333333; background-color: #f8f8f8; text-indent: 28px; font-family: 宋体; line-height: 28px; ">从 Web 服务客户端收到请求之后，Resource Request Handler 从业务逻辑层请求服务。Resource Request Handler 确定所有概念性的实体，系统将这些实体作为资源公开，并为每个资源分配一个惟一的 URI。但是，概念性的实体在该层是不存在的。它们存在于业务逻辑层。可以使用 Jersey 或其他框架（比如 Restlet）实现 Resource Request Handler，它应该是轻量级的，将大量职责工作委托给业务层。</p><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: #333333; background-color: #f8f8f8; text-indent: 28px; font-family: 宋体; line-height: 28px; ">Ajax 和 RESTful Web 服务本质上是互为补充的。它们都可以利用大量 Web 技术和标准，比如 HTML、JavaScript、浏览器对象、XML/JSON 和 HTTP。当然也不需要购买、安装或配置任何主要组件来支持 Ajax 前端和 RESTful Web 服务之间的交互。RESTful Web 服务为 Ajax 提供了非常简单的 API 来处理服务器上资源之间的交互。</p><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: #333333; background-color: #f8f8f8; text-indent: 28px; font-family: 宋体; line-height: 28px; ">图 1 中的 Web 浏览器客户端作为 GUI 的前端，使用表示层中的 Browser Request Handler 生成的 HTML 提供显示功能。Browser Requester Handler 可以使用 MVC 模型（JSF、Struts 或 Spring 都是 Java 的例子）。它从浏览器接受请求，从业务逻辑层请求服务，生成表示并对浏览器做出响应。表示供用户在浏览器中显示使用。表示不仅包含内容，还包含显示的属性，比如 HTML 和 CSS。</p><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: #333333; background-color: #f8f8f8; text-indent: 28px; font-family: 宋体; line-height: 28px; "><a href="http://images.51cto.com/files/uploadimg/20090805/1546390.jpg" target="_blank" style="color: #004276; "><img alt="多层 Web 应用程序环境图" src="http://images.51cto.com/files/uploadimg/20090805/1546390.jpg" width="498" border="0" style="border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; border-color: initial; text-align: center; border-style: initial; border-color: initial; " /></a>&nbsp;</p><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: #333333; background-color: #f8f8f8; text-indent: 28px; font-family: 宋体; line-height: 28px; ">业务规则可以集中到业务逻辑层，该层充当表示层和数据访问层之间的数据交换的中间层。数据以域对象或值对象的形式提供给表示层。从业务逻辑层中解耦 Browser Request Handler 和 Resource Request Handler 有助于促进代码重用，并能实现灵活和可扩展的架构。此外，由于将来可以使用新的 REST 和 MVC 框架，实现它们变得更加容易，无需重写业务逻辑层。</p><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: #333333; background-color: #f8f8f8; text-indent: 28px; font-family: 宋体; line-height: 28px; ">数据访问层提供与数据存储层的交互，可以使用 DAO 设计模式或者对象-关系映射解决方案（如 Hibernate、OJB 或 iBATIS）实现。作为替代方案，业务层和数据访问层中的组件可以实现为 EJB 组件，并取得 EJB 容器的支持，该容器可以为组件生命周期提供便利，管理持久性、事务和资源配置。但是，这需要一个遵从 Java EE 的应用服务器（比如 JBoss），并且可能无法处理 Tomcat。该层的作用在于针对不同的数据存储技术，从业务逻辑中分离数据访问代码。数据访问层还可以作为连接其他系统的集成点，可以成为其他 Web 服务的客户端。</p><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: #333333; background-color: #f8f8f8; text-indent: 28px; font-family: 宋体; line-height: 28px; ">数据存储层包括数据库系统、LDAP 服务器、文件系统和企业信息系统（包括遗留系统、事务处理系统和企业资源规划系统）。使用该架构，您可以开始看到 RESTful Web 服务的力量，它可以灵活地成为任何企业数据存储的统一 API，从而向以用户为中心的 Web 应用程序公开垂直数据，并自动化批量报告脚本。</p><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: #333333; background-color: #f8f8f8; text-indent: 28px; font-family: 宋体; line-height: 28px; "><strong style="font-weight: bold; text-align: center; ">什么是REST：结束语</strong></p><p style="margin-top: 10px; margin-right: 0px; margin-bottom: 10px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; color: #333333; background-color: #f8f8f8; text-indent: 28px; font-family: 宋体; line-height: 28px; ">REST 描述了一个架构样式的互联系统（如 Web 应用程序）。REST 约束条件作为一个整体应用时，将生成一个简单、可扩展、有效、安全、可靠的架构。由于它简便、轻量级以及通过 HTTP 直接传输数据的特性，RESTful Web 服务成为基于 SOAP 服务的一个最有前途的替代方案。用于 web 服务和动态 Web 应用程序的多层架构可以实现可重用性、简单性、可扩展性和组件可响应性的清晰分离。Ajax 和 RESTful Web 服务本质上是互为补充的。开发人员可以轻松使用 Ajax 和 RESTful Web 服务一起创建丰富的界面。</p><img src ="http://www.blogjava.net/czihong/aggbug/370515.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/czihong/" target="_blank">Chan Chen</a> 2012-02-22 13:21 <a href="http://www.blogjava.net/czihong/articles/370515.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>