服务端编程基本知识和一些宏观上的认识

前言

我来写写我对服务端的一些宏观上的认识.

客户端进行一次网络请求所经历的流程.

Httpflow.png

对客户端来说, 一个http 请求可以看做一个对象. 这个对象包含两部分
1.request包含url,参数等等. 2.response 内容为服务器返回的内容.
request 和 response 都分为header 和body.
header 包含从哪里来到哪里去, 以及body的数据是如何组织的,应该如何被解析.

上面这个流程大致上可以被差分为三大块.
1.客户端部分
2.network cloud
3.服务端部分.

url

一个url的例子
http://www.xxx.com:80/api/testfunction
上面的url可以拆分为以下几个部分.
协议: http
域名: www.xxx.com
端口: 80
路径: /api/testfunction

协议

http https ftp 等等.

http://www.baidu.com
https://www.baidu.com
ftp://www.baidu.com

上面三行可以分别粘贴到浏览器地址栏请求试试.

域名

www.qq.com
有的时候域名像这样 m.qq.com
m.qq.com 可以被称为qq.com 的一个子域名.
域名实际上要经过DNS解析变为ip地址才能够在互联网中对应到实际的主机.
同一个域名qq.com的不同子域名可以被解析到不同的ip地址上.

端口

端口号0--65535 共65536个. 是机器和外接通信的窗口.
常用端口号:
80 :http
443 :https

21 :ftp
22 :ssh
23 :telnet

http://www.baidu.com/xxx
上面的url没有写端口号. 但是http默认是80端口.这个请求最终会被发送到80端口.

路径

协议+域名+端口号,就可以准确在互联网上定位到服务器主机的位置了. 这个请求会被服务器网卡(硬件)接收到.

路径对应着这台服务器上面的某个文件的路径.

通过web程序,可以解析路径使其动态的对应到不同文件. 例如请求接口返回json. json可以被看做是文件. 根据请求参数返回不同json, 就是返回不同文件.

请求在服务器内部的流程

请求根据端口或者路径被分发给能够解析请求的程序, 程序将请求包装成request对象, 服务端程序员编写代码解析request对象, 查询数据库, 修改response对象, 并返回客户端.

这样一个流程中还有这些问题.
0.服务端程序员编写的代码是如何运行的.
1.根据路径分发请求的工作由谁来做.
2.根据端口分发请求的工作由谁来做.
3.一台服务器上如果有多个web项目, 他们如何同时工作. 并且互不影响.

解答:
要解答这个问题需要介绍另外的几个工具.
web服务器,和web应用服务器
例如apache, tomcat, nginx, uwsgi等.

web服务器apache, nginx
web应用服务器tomcat, uwsgi

web服务器用来初步解析请求, 转发请求.
web应用服务器处理业务逻辑(服务端程序员写的代码就用它跑起来)

web服务器可以监听端口. 下面是nginx监听规则和转发的一个例子:

server{
        listen       80 ;
        access_log /var/log/nginx/access.log;
        error_log  /var/log/nginx/error.log;

        location / {
          include         uwsgi_params;
          uwsgi_pass      unix:/data/apps/xxx/xxx/sss.sock;
        }

        location /static {
            alias /data/apps/xxx/xxx/common_static;
        }
        
        location /media {
            alias /data/apps/xxx/xxx/media;
        }
          
}        

上面是一个nginx配置.
修改nginx配置到上面形式, 意味着nginx会监听80端口的所有请求,
请求处理成功则会/var/log/nginx/access.log修改日志文件添加记录
处理失败则/var/log/nginx/error.log修改这个文件添加记录

所有请求会被转发给 uwsgi服务器, uwsgi服务器监听的端口为/data/apps/xxx/xxx/sss.sock (Linux系统中端口和文件都被抽象成文件. 反过来监听端口也可以变成监听文件.)

uwsgi或者tomcat用来运行程序员编写的代码.

所以上面的问题
0.服务端程序员编写的代码是如何运行的.
是由web应用服务器例如tomcat uwsgi 运行的.

1.根据路径分发请求的工作由谁来做.
由web服务器来做. apache, nginx 这些根据url或者端口号将请求分发给其他端口或者web应用服务器.

2.根据端口分发请求的工作由谁来做.
监听端口就是程序向操作系统注册监听某个端口. 操作系统将该端口收到的所有内容发送给监听此端口的程序.

3.一台服务器上如果有多个web项目, 他们如何同时工作. 并且互不影响.
根据不同的部署情况有所不同.举几个例子.
apache tomcat, tomcat目录下有一个webapps目录, webapps目录下是不同的web项目的文件. 不同项目的文件夹的名字需要包含在url中. tomcat默认监听8080端口(可修改)

一个请求tomcat下某java项目的例子
http://xxx.xxx.xxx:8080/myfirstapp/api/getjson
上面的url首先被apache接收到. 根据端口号之后路径中的第一部分/myfirstapp/ 这个请求会被转发给tomcat/webapps/目录下名为 myfirstapp的项目. 项目根据/api/getjson将请求转发给对应接口. 生成并返回json.

最后不同的webapp项目 可以分别监听url中的某一部分, 也可以监听不同的操作系统端口, 甚至监听不同的文件.

一个简单的服务端程序的结构.

和iOS程序会使用MVC架构一样. 服务端程序也流行MVC架构. 与iOS相比服务端程序会多出一些概念. 在介绍这几个工具前, 有这样几个思想需要知道. 这几个思想在服务端编程中到处都有体现.
1.MVC
2.AOP
3.池化的思想

MVC

MVC是一种思想.m(Model),v(View),c(Control)

一般的在iOS中M仅代表数据. V代表视图代码或者xib or storyboard文件. C表示控制器controller.
以上三种都可以根据需求拆分成多个类, 或者多个文件. 例如一个页面由很多个view 组成, 这个页面对应的controller 也可以被拆分成多个对象的组合, 对象之间使用某种方式进行通讯.

服务端的MVC
M通常也是模型, 如果有使用ORM框架, 那么M部分就是结构和对应数据库表一致的对象. 也就是说M在大多数情况下可以近似的看做是数据库表.

V代表视图. 对服务器来说静态的HTML文件是视图, json串是视图. jsp, asp之类的也是视图. 甚至音频文件, 视频文件也可以是视图. 这些东西在服务端看来都可以被抽象成"视图", "视图"不光可以是静态文件, 也可以根据请求参数动态的生成!!!

C代表控制器. 也可以说就是具体的业务逻辑. 在控制器中解析参数, 根据参数生成视图并返回. python的django框架中控制器代码一般写在views.py文件中

AOP思想

AOP(面向切片)

服务端的工作流程可以抽象成这样的流程

interceptor.png

interceptor 拦截器的数量不确定. 数目0--n都可以. interceptor 拦截器可以用来过滤数据, 对数据做初步处理, 校验参数, 检查请求权限(非法请求在这里就被拦截了) 等等.

这个过程组成一个完整链条. 整个过程可以被看做是一个一个组合起来的切片. 每一个切片之间影响不大.
每个切片将符合自己逻辑的数据流对象传递到下一个切片. 这样就是面向切片的思想了. 就像流水线 每个切片负责自己的工作, 对请求对象处理完毕之后传递到下一个切片.

池化的思想.

列举几个池化的例子.
iOS中的UITableView 复用池.
数据库连接池.
线程池
TCP连接池.

也即是将可以重复使用的资源, 不销毁不释放, 将它们放入一个池子中, 当有新的资源需求时直接从池子中获取. 当然池子的大小是有限制的.

一个简单的服务器框架的组成部分.

1.配置文件.
2.数据库操作
3.业务逻辑
4.依赖管理
5.日志系统,异常处理

配置

java xml配置. python django配置文件:settings.py 对应iOS中就是.plist文件

数据库操作

例如iOS中的FMDB或者其他的ORM(object relationship mapping对象关系映射)框架.
django自带ORM.非常好用.

业务逻辑

django中业务逻辑一般写在views.py文件中. iOS中写在controller中.
但是相比OC,python中有一个新的工具叫做装饰器.

catchexception.png

上图 对post方法添加了一个装饰器, 叫做catch_exception,作用顾名思义就是捕获异常...
理解装饰器, 最好能理解aop思想, 装饰器就是在post方法这个切片外面套了一层.

依赖管理

iOS中会使用cocoapods 进行依赖管理. python 中使用pip 进行依赖管理. 具体如何进行会在以后介绍.

日志系统

iOS中有崩溃日志收集工具. 服务端项目会记录非常详细的日志. 做一些简单配置即可. 日志会被单独保存在服务器的指定目录下.

你可能感兴趣的:(服务端编程基本知识和一些宏观上的认识)