问题说明
在昨天的总结中,对于6月10日的Workshop进行了一定程度的归纳和总结,在后续与老师的讨论中,发现部分未接触过的内容只是理解了字面上的意思,并未进行深入的思考,先对其中部分问题的解答做记录,以备日后查阅。
一、 HTTP请求的状态问题
原文如下:
互联网通信协议HTTP协议,是一个无状态协议。这意味着,所有的状态都保存在服务器端。因此,
如果客户端想要操作服务器,必须通过某种手段,让服务器端发生"状态转化"(State Transfer)。
而这种转化是建立在表现层之上的,所以就是"表现层状态转化"。
(引用自:阮一峰博客“理解restful构架”)
原文中提到,互联网通信协议HTTP协议,是一个无状态的协议,在昨天的总结中,只是对这个概念做了单纯的记忆,没有去理解何为状态。
协议的状态:
百度百科给出的解释是:
协议的状态是指下一次传输可以“记住”这次传输信息的能力.
——百度百科
-
无状态协议:[ HTTP协议 ]:
前文中提到了,互联网通信协议HTTP协议,是一个无状态的协议。说明了HTTP协议中,为了保证服务器的内存,HTTP不会为了下次连接而维护这次连接所传输的信息。 -
有状态协议:[网络游戏通信协议(这里我没有查到具体使用的协议,后续了解到会补充进来)]
众所周知,网络游戏在进行过程中,需要一次登录,登录过后服务器不会再去要求登录才能访问URI,这就说明了,在用户第一次登陆之后,用户自身的请求会携带一个“已登陆”的状态。后续用户跟服务器的交互过程中,服务器会自动识别这个“已登录”的状态,而不会再要求用户去登陆才能访问资源。
无状态协议在一些特定情况下的补充:
-
Q:已知HTTP协议是一个无状态的协议,那用户在访问类似Baidu这样的网站时,已登录的状态该如何处理?
-
A:利用cookie。
1、当你发送第一个请求的时候,服务器会生成一个随机的字符串,然后在服务器空间内分配一段内存空间,这个内存段的索引就是这个字符串(为方便叙述,这个字符串暂定为123);
2、“123”会随着HTTP的Response返回给浏览器,浏览器会将它存入Cookie中;
3、此时我们输入用户名和密码,会像服务器发送登录请求,request中会包含“123”;
4、服务器接受到请求后,验证用户名密码的正确性,验证后会根据索引“123”,找到之前分配的内存空间(session),在空间内加入“已登陆”的标志。
5、再次之后,我们的每个请求都会带有“123”这个索引,服务器会根据这个索引找到内存段,如果有“已登陆”的标志,有则正常访问,无则跳转登陆界面。
二、RestAPI的架构问题
根据上述,我们可以获得一个信息,在所有http都会带有cookie的先决条件下,任何http请求都会由request带来状态,也就是说service理论是能够知道请求的状态的。
但根据前文讲述,服务器不应该知道请求的状态,否则会造成过度的负载,有悖于我们之前讲述的RestAPI的架构。所以在可用性上,RestAPI的架构风格做了两个方面的约束:
- 状态由客户端提供;
- Service不保存状态。
在这两个方面的约束下,我们可以得知,状态需要一个空间来存放,那么这时候有两种选择:
1、 存放在数据库中
这种方法简明有效,但同时也面临一定的风险,数据库本身的存储就具有一定的风险,所以这里我们不提倡
2、存放在类似redis集群式的内存存储里
这种方法具有速度快、多个备份节点等优点
综上,现在的RestAPI构架所提倡的组合:
客户端——Service——State Storage ——数据库。
ps:新名词解释:redis:
redis是一个key-value存储系统。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set --有序集合)和hash(哈希类型)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,redis支持各种不同方式的排序。与memcached一样,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。
——来自百度百科
(于6月25日补充,未完待续)
网友评论