Web Application背后的那些事儿

当你在地址栏中输入” www.google.com" 之后发生了什么?

  • 首先浏览器会识别 URL 地址: 包括协议( http/https/ftp), 域名 google.com, 以及它对应的端口号. http 默认端口号为 80, https 端口号为 443, ftp 端口号为 21.
  • 浏览器会现在各种 cache ( browser cache, OS cache, DNS cache, etc)中查找, 如果都找不到就把任务丢给 ISP’s DNS (Internet Service Provider).
  • ISP 作为服务供应商, 积极本着积极响应客户需求的原则从高到低, 从远到近的进行递归搜索. 直到找到这个地址所在的所有服务器, 返回最近的, 效果最好的那个地址给浏览器.
  • 浏览器就就可以骚骚的拿着这个地址向服务器发送请求( get, post, etc).
  • 服务器会返回给浏览器一个确切的地址.
  • 现在浏览器确认这个地址是有效的了, 然后不要脸的又发送了一次一模一样的请求.
  • 这一次 server 会派 handler 来处理这个请求, 读取它的参数, (以及更新服务器端的内容).
  • handler 结束工作之后会生成一个 HTML 的回复, 然后服务器会把这个回复交给浏览器. (HTTP/1.1 200 OK)
  • 浏览器收到这个回复之后就会可视化这个 HTML 的内容, 并且向服务器发送读取内容的请求并接收这些文件. (Images, CSS, JS files, etc)

所谓协议是为了让双方通讯可以理解, 这里通常我们会使用 HTTP 协议. 为了确保和目标进程链接正确, 使用 TCP 协议. IP 地址是为了保证请求能发送到正确的机器上.


对一个 Web Application 来说, 它的职能范围就是在客户端和服务器端收到请求之后,能够正确处理.

关于 Tomcat
就是一个用来处理各种 Web Application 基本操作的框架. 例如如何接受 HTTP 的请求, 如何发送 HTTP 的结果, 如何调用与 HTTP 请求相关的进程, 如何建立 TCP 的链接, 以及建立连接后如何把 HTTP 请求的处理结果返回给客户端. 它可以运行在本地或者远程服务器上.
作为开发人员只需要处理接收到请求之后和返回结果这件的这一段时间内的需要做的操作. 大大简化了开发人员的操作复杂度.

一个简单的 Web Application 会遵循一个简单的 3 层逻辑: PLD

  • Presentation Tier: 如何展示给客户
    Frontend HTML, CSS, Javascript, etc.
  • Data Tier: 如何存储数据
    SQL MongoDB, MySQL, etc.
  • Logic Tier: 如何处理数据
    Backend Java, Go, Python, etc.

简述 HTTP 请求:

  • Request Line ( 请求类型( get, post, etc) , 访问的资源( host 地址的相对路径,访问之后触发的路径), HTTP/1.1(协议版本))
  • Request Header (额外信息, 支持语言, 浏览器类型等)
  • Request Message Body (对内容进行更改)

HTTP RESPONSE:

  • Status Line ( 协议版本, 状态码 200, 404, 500, etc., 状态信息)
  • Response Headers (Server 版本, 返回类型, etc)
  • Response Message Body

对于 Message Body 通常使用 Json (Javascript Object Notation)格式, 比起 XML 更加简洁, 而却 key, value pair 的搜索效率更高.
RPC (Remote Procedure Call): 对于 HTTP 请求进行处理然后返回相对应的结果这个过程.
对于 Java 来说, Java Servlet 是专门用来处理客户端发到服务器端的请求的(rpc).

通常使用 HTTP 的请求类型是 Get 和 Post. 那么为什么偏向于用 Post 而不是用 Put 呢?
因为 Put 是幂等( idempotent) 的操作, 而 Post 不是. 什么是幂等呢?
对于一个操作和多个操作产生的结果是相同的, 这种操作叫做幂等. 而每一个操作产生的结果都不相同的操作成为非幂等操作.
如果对某个文件进行一个更新操作, 我们希望保持结果的一致性.所以使用 Post.

简述 URL:

protocal://hostname:port/endpoint?query
通常 port 是不写的, 因为 每一个 protocal 有默认的端口号码. 除非我们希望监听特定的某个进程.
endpoint 对应的是我们希望触发的的进程.

使用 REST 设计 Web Service:
使用 HTTP method 对应请求, 减少服务器端的操作, 直接通过 HTTP request 判断用户需求.
server 可以通过 URL 来判断请求对应的是哪一个文件/进程( service).
请求和请求之间相互独立的, server 就不需要记录一个请求的状态以便于处理下一个请求(处于 stateless 状态).每个请求对应一个操作.
提升数据处理量, 因为每一个请求都是相对独立的, 所以 server 不需要记录任何一个请求来处理下一个请求,因此 server 是无状态的, 所以当进行扩展的时候不需要考虑 server 的状态, 可以简单的使 server 运行在多个不同的机器上(平行扩展). 扩展性能高( scalibility).

DataBase:
ER (Entity Relationship) model: 只包含两种数据类型( Entity( 可以实例化), Entity 之间的关系(不能实例化))
MySQL: Widely used open source relational database manaegement system.

  • Table: 拥有相同属性的数据集合. 每一列对应一个属性.
  • Row: 包含完整信息的一个 item.
  • Column :属性.
  • Schema: table 创建时候的结构(都有什么属性, 每一种属性有什么类型, 其他限制条件等).
  • Consistency: 保持一致性, 但是慢. 数据耦合度高.

NoSQL: Json-like distributed system using horizontal scaling. No schema. More flexible.

  • Collection: 数据集合.不要求每一条数据拥有相同的属性.
  • Document: 包含完整信息的一个 item.
  • Field: 属性. (may vary from document to document)
  • Avalibility: 及时同步, 速度快. 但是数据有可能不太一致.数据之间的耦合度低.

CAP:

  • Consistency: Every request will receive the most recent data.
  • Availability: Every request will receive a response, which may not be up to the minute, without delay.
  • Partition tolerance: Trade off consistency and availability for distributed system.