新普金娱乐网址


周密谈字符串及其格式化表达式

数学《聊聊标签效应》

晓HTTP幂等性(转)

  • 十月 27, 2018
  • 数学
  • 没有评论

Calculator V1.0

基于HTTP协议的Web
API是现阶段最为盛行的一致种分布式服务提供方。无论是当巨型互联网采用或企业级架构中,我们还看了越来越多之SOA或RESTful的Web
API。为什么Web
API如此流行为?我道甚特别程度达到答应归功给简单实用之HTTP协议。HTTP协议是如出一辙种分布式的面向资源的大网应用层协议,无论是服务器端提供Web服
务,还是客户端消费Web服务都非常简单。再长浏览器、Javascript、AJAX、JSON以及HTML5等技巧与工具的开拓进取,互联网使用架构设
计表现来了起人情的PHP、JSP、ASP.NET等劳务器端动态网页为Web API +
RIA(富互联网使用)过渡的大势。Web
API专注于提供业务服务,RIA专注让用户界面及相互设计,从此两只世界的分工更为分明。在这种动向下,Web
API设计将化服务器端程序员的必修课。然而,正而简单的Java语言并无表示强质量之Java程序,简单的HTTP协议也无代表强质量之Web
API。要想设计有赛质量的Web
API,还需要深刻明分布式系统及HTTP协议的特色。

注:这是一个C++计算器项目之起部分。

幂等性定义

正文所设追究的亏HTTP协议提到到之平等栽重大性质:幂等性(Idempotence)。在HTTP/1.1规范被幂等性的概念是:

Methods can also have the property of “idempotence” in that (aside
from error or expiration issues) the side-effects of N > 0
identical requests is the same as for a single request.

从今概念及看,HTTP方法的幂等性是依同一次同频繁请某一个资源应该有同等的副作用。幂等性属于语义范畴,正使编译器只能救助检查语法错误一
样,HTTP规范为无辙通过信息格式等语法手段来定义其,这或许是它不绝中推崇的来由有。但骨子里,幂等性是分布式系统设计中杀重中之重之概念,而
HTTP的分布式本质也控制了它于HTTP中装有至关重要位置。

大致功能简介:
  • 会输入一失误数学表达式
  • 逐字符扫描,提取数字和标记得到同组队列
  • 逐行输出提取的记和数字

分布式事务 vs 幂等设计

干什么用幂等性呢?我们事先打一个例子说自,假设有一个打账户取钱的远程API(可以是HTTP的,也可免是),我们少用类函数的道记为:

bool withdraw(account_id, amount)

withdraw的语义是自从account_id对应之账户被扣除amount数额的钱;如果扣除成功则归true,账户余额减少amount;
如果扣除失败则回false,账户余额不转移。值得注意的凡:和本土环境相比,我们无克随便而分布式环境之可靠性。一栽典型的情事是withdraw请
求已经于劳动器端正确处理,但劳动器端的回结果由于网络等由为丢丢了,导致客户端无法获悉处理结果。如果是于网页上,一些非适宜的设计也许会见使用户认
为上一样潮操作失败了,然后刷新页面,这便招致了withdraw被调用两不良,账户为为多扣了平等不善钱。如图1所显示:

数学 1

图1

这个题材的解决方案一凡是采用分布式事务,通过引入支持分布式事务的中级件来保证withdraw功能的事务性。分布式事务之独到之处是对此调用者很简
单,复杂性都付了中等件来治本。缺点则是一边架构太重量级,容易被捆在一定的中等件及,不便利异构系统的合龙;另一方面分布式事务虽然能够确保工作之
ACID性质,而可可力不从心提供性与可用性的保险。

别一样种植更轻量级的化解方案是埋等统筹。我们好透过一些技能把withdraw变成幂等之,比如:

int create_ticket() 
bool idempotent_withdraw(ticket_id, account_id, amount)

create_ticket的语义是得到一个劳务器端生成的绝无仅有的拍卖号ticket_id,它用用来标识后续之操作。
idempotent_withdraw和withdraw的分别在关联了一个ticket_id,一个ticket_id表示的操作及多独会吃拍卖一
次,每次调用都以回到第一浅调整用时之处理结果。这样,idempotent_withdraw就称幂等性了,客户端就得放心地反复调用。

据悉幂等性的解决方案面临一个圆的取钱流程被解释成了简单单步骤:1.调于是create_ticket()获取ticket_id;2.调用
idempotent_withdraw(ticket_id, account_id,
amount)。虽然create_ticket不是幂等的,但以这种规划下,它对网状态的震慑可以忽略,加上idempotent_withdraw
是幂等的,所以任何一样步由于网络等原因失败或过期,客户端都好重试,直到获得结果。如图2所展示:

数学 2

图2

同分布式事务相比,幂等计划的优势在她的轻量级,容易适应异构环境,以及性能与可用性方面。在某些性能要求比强的行使,幂等规划反复是绝无仅有的选。

实现代码如下:
  • scan.h

    #ifndef _SCAN_H_
    #define _SCAN_H_
    #include<string>
    #include<iostream>
    #include<queue>
    using std::string;
    using std::queue;
    class Scan{
    queue<string> expression;    //用于接收表达式
    bool isDigit(char c);       //判断是否是数字或'.'
    void numErr();              //当数值超过10位后报错
    public:
    Scan(){};                        //    ->暂无
    ~Scan(){};                       //    ->暂无
    queue<string> getExp(){return expression;}  //返回expression队列的内容
    queue<string> toStringQueue(string );  //toStringQueue将string的内容逐字符提取转换为string队列
    }; 
    #endif
    
  • print.h

    #ifndef _PRINT_H_
    #define _PRINT_H_
    #include<iostream>
    #include<string>
    #include<queue>
    using namespace std;
    class Print{
    // parameter 
    public:
    Print(){};    //暂无
    ~Print(){};     //暂无
    bool putq(queue<string> output); //逐行输出string队列
    };
    #endif
    
  • Calculator.cpp

    #include<iostream>
    #include<string>
    #include"scan.h"
    #include"print.h"
    int main()
    {
        using namespace std;
        string exp;         //exp用来接收键盘输入的表达式
        getline(cin,exp);
        Scan input;
        Print output;
        output.putq( input.toStringQueue(exp)); //调用input类的toStringQueue方法,返回一个<string>的队列,传入output的putq方法输出队列
        cin.get();  
        return 0;
    }
    
  • scan.cpp

    #include"scan.h"
    bool Scan::isDigit(char c)                                      //判断是否是数字或句点
    {
        if( (c<='9'&&c>='0')|| c=='.')return true;
    
        return false;
    }
    
    void Scan::numErr()
    {
        std::cout<<"numerical ERROR\n";
        std::cin.get();
        std::exit(-1);
    }
    
    queue<string> Scan::toStringQueue(string input)
    {
        int i=0,dlen=0;         //i用于循环,dlen用于表示数值长度
        int len=input.length(); //用input的长度len来作为循环条件
        string& c=input;    //用c来代替input不然打的太累了=。=
        string temp="";     //temp用来暂储input中的元素
        while( i<len){
            if(isDigit(c[i]) ){
                temp+=c[i];
                dlen++;
                if(dlen>10)numErr();        //判断数值是否超出范围
                if( (i+1)<len && isDigit(c[i+1]) && ++i ) continue; //判断是否还有下一个字符以及下一个字符是不是数字或句点,若是++i跳回循环开头,
                                            //    否则,将条件后的数个语句执行
            }
            else temp=c[i];
            dlen=0;                             /重置dlen
            expression.push(temp);          //将temp推入队列
            temp="";
            i++;
        }
        return expression;
    }
    
  • print.cpp

        #include"print.h"
        bool Print::putq(queue<string> output)
        {
            int count=0;     //count计数确保输出正确
            while( !output.empty() ){
                cout<<output.front()<<endl;
                output.pop();
                count++;
            }
            return count==output.size();  //返回输出个数是否正确的布尔值
        }
    

    源于文件可以在github上下载


HTTP的幂等性

HTTP协议本身是一样种植面向资源的应用层协议,但针对HTTP协议的行使实际上有正在些许种植不同之艺术:一种是RESTful的,它将HTTP当成应用
层协议,比较忠实地遵守了HTTP协议的各种规定;另一样种是SOA的,它并无完全将HTTP当成应用层协议,而是将HTTP协议作为了导层协商,然后
在HTTP之上建立了团结的应用层协议。本文所讨论的HTTP幂等性主要对RESTful风格的,不过正而达到平等节所看到底那么,幂等性并无属特定的协
议,它是分布式系统的等同栽特色;所以,不论是SOA还是RESTful的Web
API设计还应该考虑幂等性。下面将介绍HTTP
GET、DELETE、PUT、POST四栽重点方式的语义和幂等性。

HTTP GET方法用于取资源,不该副作用,所以是幂等的。比如:GET
http://www.bank.com/account/123456,不会改变资源的状态,不论调用一次还是N次都没有副作用。请注意,这里强调的是
一潮和N次具有同等之副作用,而非是历次GET的结果一律。GET
http://www.news.com/latest-news这个HTTP请求可能会每次得到不同的结果,但它本身并没有产生任何副作用,因而是满足
幂等性的。

HTTP DELETE方法用于去资源,有副作用,但它们应该满足幂等性。比如:DELETE
http://www.forum.com/article/4231,调用一次和N次对系统产生的副作用是相同的,即删掉id为4231的帖子;因此,
调用者可以屡屡调用或刷新页面而不要担心引起错误。

较好混淆视听的凡HTTP
POST和PUT。POST和PUT的分容易吃概括地误认为“POST表示创建资源,PUT表示更新资源”;而事实上,二者都只是用于创造资源,更为本质之差距是以幂等性方面。在HTTP规范着针对POST和PUT是这么定义之:

The POST method is used to request that the origin server accept the
entity enclosed in the request as a new subordinate of the resource
identified by the Request-URI in the Request-Line …… If a resource
has been created on the origin server, the response SHOULD be 201
(Created) and contain an entity which describes the status of the
request and refers to the new resource, and a Location header.

The PUT method requests that the enclosed entity be stored under the
supplied Request-URI. If the Request-URI refers to an already existing
resource, the enclosed entity SHOULD be considered as a modified
version of the one residing on the origin server. If the Request-URI
does not point to an existing resource, and that URI is capable of
being defined as a new resource by the requesting user agent, the
origin server can create the resource with that URI.

POST所对应之URI并非创建的资源本身,而是资源的收信人。比如:POST
http://www.forum.com/articles的语义是在http://www.forum.com/articles下创建一篇帖
子,HTTP响应中答应包含帖子的缔造状态与帖子的URI。两次等同之POST请求会在劳动器端创建两客资源,它们有着不同之URI;所以,POST方法
不备幂等性。而PUT所对应之URI是如果创建或者更新的资源本身。比如:PUT
http://www.forum/articles/4231的语义是创建或更新ID为4231的帖子。对同一URI进行多次PUT的副作用和一次
PUT是同等的;因此,PUT方法有幂等性。

于介绍了几种植操作的语义和幂等性之后,我们来探哪通过Web
API的款型落实前面所涉及的取款功能。很简短,用POST
/tickets来兑现create_ticket;用PUT
/accounts/account_id/ticket_id&amount=xxx来实现idempotent_withdraw。值得注意
的是严来讲amount参数不应有作为URI的一样片段,真正的URI应该是/accounts/account_id/ticket_id,而
amount应该置身要的body中。这种模式可以利用为博场合,比如:论坛网站被预防意外的复发帖。

代码编写过程遇到的题材:

  这次的题目不是颇为难,尤其是后来题目一直于变更简单,所以代码写得为比较流利。
  不过本编写Print类时,根本无晓得queue是呀数据类型,于是就失去百度了成百上千,不敢说还懂了,但是至少会用了。
  除了部分边边角角的题目外,在第一不成编写了toStringQueue方法后登了疯之调剂状态,bug不歇的面世,原始代码如下

数学 3

  当时的想法是逐字符提取,

  •  若是字符则一直push(temp)
  •  若是数字temp+=c[i++],把数字接到temp上

    •  再判断下一个c[i] 是否也是数字

      • 凡,就拿生一个收到temp后面,dlen++
      • 否,就push(temp),重置temp和dlen

自己之IDE是vs2010,编译过了,但是运行的时候会弹出警告“ string subscript
out of range

string
下标越界,一开始百度并不曾亮是及时意思,一直当搜索是未是自己哪里的指针或者什么的没初始化或者哪里进了死循环

数学 4

新生当DEBUG模式下才找到罪魁祸首,上面这话中,当i不小于len后先后于下运作

数学 5

可是运行至箭头处经常,此时底c[i]现已过下标范围了,之后同时同样潮i++了,

与此同时于脚这步的巡回条件中之dlen++<=10出摩擦,这让数值最可怜而直达11位

数学 6

先是蹩脚写的此函数的逻辑有点乱,把地方装有bug总结了千篇一律举后,开始大换血,重新勾了一个逻辑稍清晰的,正确运行。


总结

点简单介绍了幂等性的定义,用罩等规划取代分布式事务之艺术,以及HTTP主要方法的语义和幂等性特征。其实,如果要是迎头赶上到底溯源,幂等性是数学中之一个概念,表达的是N次变换与1不良变的结果一致,有趣味之读者可从Wikipedia上更是询问。

末了……当然是总啦:

盖一个休小心,耗费了协调一下午时光来debug,简直血以及泪水的代价啊,事实告诉要好后写程序要要多想一会,否则大把死把的辰纵如此没有了,同时也劝告自己从此如果多注重程序的逻辑,这样才能够写来更结实的代码来。

当高校在之第一独C++项目,肯定起成百上千不足之处,欢迎看罢之各位给本人批评以及建议,谢谢!

相关文章

No Comments, Be The First!
近期评论
    分类目录
    功能
    网站地图xml地图