Final Project:利用java 实现web Server
写在前面:127.0.0.1是什么地址?
127.0.0.1与localhost?
题目1.1 开发一个简单的webServer1.0
HTTP:超文本传输协议描述了程序可以通过IP交换数据的一种方式。
GET:获取信息/POST:提交表单数据或上传文件
一个标头称为Content-Length
,告诉服务器在请求正文中期望读取多少字节。
- 当client联系时创建一个连接socket.
- 从这个socket作为门接受HTTP请求
- 解释该请求以确定所请求的特定文件
- 从Server的FS处获得请求的文件
- 创建一个由请求的文件组成的HTTP响应报文
- 经过TCP连接向请求的浏览器返回相应。
参考实验楼的实验,用python实现http Server
实验楼的还不如原文讲的清楚…
python代码如下:
1 | #-*- coding:utf-8 -*- |
BaseHTTPRequestHandler类帮我们处理对请求的解析,通过请求的方法来调用其对应的函数。
如方法是GET
, 该类会调用名为do_GET方法。
我们所重写的RequestHandler重写此方法以动态生成一个简单的页面:文本存储在类级别的变量中Page,
使用httpie
代替浏览器发送请求并在终端打印相应信息。
?postman?
要显示的页面模版只是一个字符串而已,包含html
进阶 使其显示值
修改Web服务器以显示HTTP请求中包含的某些值以用于调试
代码框架如下:
1 | class RequestHandler(BaseHTTPServer.BaseHTTPRequestHandler): |
在地址栏输入地址一般就是GET
注意此时即使页面上并没有我们要寻找的something.html我们也不会收到404NotFound:
web服务器只是一个程序!
那如何让我们在没有sth.html的时候显示404Not Found呢?
- 为我们的服务器编写一个异常类:
1 | class ServerException(Exception): |
从FS(磁盘)提供页面
下一步是从磁盘开始提供页面,而不是生成即使页面。
1 | def do_GET(self): |
存疑
不知道为什么httpie可以成功显示,但chrome暂时无法显示呢?
在根URL显示首页内容
直接在根URL显示主页内容,此时就涉及到了条件判断的问题。
Case1:该路径不存在
Case2:该路径是文件
Case3:default class
Problems:
- httpPOST和GET区别。
- postman测试的使用方法
- 什么是简单的HttpWeb代理服务器?
HTTP普通代理
Client首先发送Http Connect请求给proxy,发送RealServer信息
代理服务器建立和RealServer的连接, ?并向浏览器回应Connection Established
建立连接
浏览器将请求发送给proxy,proxy传给RealServer
RealServer ->Response->Proxy->Client
这个代理将是多线程的,使其在相同时间能够处理多个请求。?
测压的client端进行压测?
分析现有能支持同时连接的最大数,修改代码使服务器同时支持1000个连接?
NIO?
使用Java NIO 提高服务端程序的性能。
线程池?
Netty 是一个 NIO 客户端服务器框架
7.21更新,原来一直都是filePath写错了…
就好啦!
心好累 一堆Error…
7.23更新,原来,哎就不是所有代码都能借鉴的。
原来的代码无法同时更新,即我先输入index.html/再输入其他无效路径,无法显示我第二次输出的值,且postman测试也不通过。
Postman测试,就是在命令行输入:
http GET 'URL'
http POST 'URL'
测试其返回结果。
7.24更新啊,终于把最简单的http写出来了
逻辑真的很简单,就是莫名其妙的会报错,绝了。
v1.1代码如下:
1 | import java.io.*; |
基于线程池技术的http服务器
java线程池是什么
原来使用的线程也是一种对象,频繁的创建和销毁对象是对性能消耗比较大的一件事。
即原有的new Thread(){public void run{}业务逻辑}.start()
使用线程池的优点
- 线程的使用率提升
- 线程池可以控制线程数,有效避免了资源不足的问题
线程池的分类方式:
newFixedThreadPool:指定线程池中的线程数
两个结果综合说明,newFixedThreadPool的线程数是可以进行控制的,因此我们可以通过控制最大线程来使我们的服务器打到最大的使用率,同事又可以保证及时流量突然增大也不会占用服务器过多的资源。
http代理服务器
是这个代理的过程采用多线程和线程池啊…
折腾一上午以为是responseHandler进行多线程。
代理的过程多线程,看看逻辑好像还是request/response.
代理服务器是什么
代理服务器:
- 解析http请求头消息,
- 找到目标服务器
- 建立代理服务器到目标服务器的socket连接
- 将http消息进行转发
是http代理,而无需https代理。
NIO优化
更高效的I/O处理模型
使用NIO的网络新特性,构建高性能非阻塞并发服务器。
常见I/O模型:
- 阻塞I/O
- 非阻塞I/O
- I/O复用
- 信号驱动I/O
- 异步I/O
NIO与BIO?
搜索words: 利用javaNIO实现高并发代理服务器
- NIO和被IO有着相同的目的和作用,但是它们的实现方式不同
- NIO以块方式处理数据,非阻塞
- BIO以流方式处理数据,阻塞
NIO的核心部分
- Channel
- Buffer
- Selector:用于监听多个通道的事件,即使用单个线程可以监听多个数据管道
- BIO中的stream是单向的,例如FileInputStream对象只能进行读取数据的操作,而NIO中的通道(Channel)是双向的,既可以用来进行读操作,也可以用来进行写操作。
NIO 使用一个线程处理大量的客户端连接。
NIO核心API
EventLoopGroup和其实现类NioEventLoopGroup
EventLoopGroup是一组EventLoop的抽象,Netty为了更好的利用多核CPU资源,一般会有多个EventLoop同时工作,每个EventLoop维护着一个Selector实例。
在Netty服务器端编程中,我们一般都需要提供两个EventLoopGroup,例如:BossEventLoopGroup和WorkderEventLoopGroup。
通常一个服务端口即一个ServerSocketChannel对应一个Selector和一个EventLoop线程。BossEventLoop负责接收客户端的连接并将SocketChannel交给WorkerEventLoopGroup来进行IO处理,
常用方法:
构造方法:NioEventLoopGroup()
ServerBootstrap和Bootstrap
ServerBootStrap是Netty中的服务端启动助手
BootStrap是Netty中的客户端启动助手
利用这两个API完成各种配置。
Selector
检测多个注册的Channel上是否有时间发生,然后针对每个事件进行相应的响应处理。
这样使得只用在连接真正有读写时,才会调用函数来进行读写,大大地减少了系统开销。
NIO与Netty?
Netty是基于NIO的网络编程框架,使用Netty相当于简化和流程化了NIO的开发过程。
tdl1:NIO与Netty基础
Tdl2:https://www.zhihu.com/question/19732473/answer/241673170
tdl3:Java NIO浅析
Netty框架
【无】哈哈哈。
Netty就是好用的bio诶,Netty包还要引入Orz。
导入居然是在Mavens吗哈哈?
功能和性能需求:分析能支持同时连接的最大数,修改代码使服务器可以同时支持1000个连接,此时需要使用NIO进行优化。
http Server 代码逻辑–伪代码
1 | { |
性能层面
经典的每连接没线程的模型(BIO)模型性能较低的本质在于严重依赖线程。
使用Netty对Http服务器的简单优化
https://blog.csdn.net/qq_21260033/article/details/80118349
Postman也有软件诶
使用PostMan进行压力/性能测试
http服务器
V1.0 BIO(Done)
V1.1加入线程池(Done)
V2.0采用Netty框架。(Done)
http代理服务器
代理服务器的基本逻辑:
- 等待来自客户端(web browser)的请求
- 启动新线程处理客户端请求。