从01开始 从01开始
首页
  • 计算机科学导论
  • 数字电路
  • 计算机组成原理

    • 计算机组成原理-北大网课
  • 操作系统
  • Linux
  • Docker
  • 计算机网络
  • 计算机常识
  • Git
  • JavaSE
  • Java高级
  • JavaEE

    • Ant
    • Maven
    • Log4j
    • Junit
    • JDBC
    • XML-JSON
  • JavaWeb

    • 服务器软件
    • Servlet
  • Spring
  • 主流框架

    • Redis
    • Mybatis
    • Lucene
    • Elasticsearch
    • RabbitMQ
    • MyCat
    • Lombok
  • SpringMVC
  • SpringBoot
  • 学习网课的心得
  • 输入法
  • 节假日TodoList
  • 其他
  • 关于本站
  • 网站日记
  • 友人帐
  • 如何搭建一个博客
GitHub (opens new window)

peterjxl

人生如逆旅,我亦是行人
首页
  • 计算机科学导论
  • 数字电路
  • 计算机组成原理

    • 计算机组成原理-北大网课
  • 操作系统
  • Linux
  • Docker
  • 计算机网络
  • 计算机常识
  • Git
  • JavaSE
  • Java高级
  • JavaEE

    • Ant
    • Maven
    • Log4j
    • Junit
    • JDBC
    • XML-JSON
  • JavaWeb

    • 服务器软件
    • Servlet
  • Spring
  • 主流框架

    • Redis
    • Mybatis
    • Lucene
    • Elasticsearch
    • RabbitMQ
    • MyCat
    • Lombok
  • SpringMVC
  • SpringBoot
  • 学习网课的心得
  • 输入法
  • 节假日TodoList
  • 其他
  • 关于本站
  • 网站日记
  • 友人帐
  • 如何搭建一个博客
GitHub (opens new window)
  • JavaSE

  • JavaSenior

  • JavaEE

  • JavaWeb

    • 服务器软件

      • 什么是服务器软件
        • Web相关概念回顾
        • 什么是服务器软件
        • 自己实现服务器软件
        • 常见的Web服务器软件
      • Nginx介绍
      • Nginx的安装和启停
      • Nginx配置
      • Nginx配置反向代理
      • Nginx配置多个反向代理
      • Nginx配置负载均衡
      • Nginx配置动静分离
      • Nginx集群概念
      • Nginx配置高可用(主从)
      • Nginx原理
      • Nginx日志管理
      • Nginx手册
      • Nginx系列完结
      • Tomcat介绍
      • Tomcat安装和启停
      • Tomcat配置
      • Tomcat部署项目
      • IDEA新建JavaWeb项目
      • Tomcat集群
      • 服务器软件
    • 环境管理和配置管理-科普篇
    • Servlet入门

    • JavaWeb
  • Spring

  • 主流框架

  • SpringMVC

  • SpringBoot

  • Java并发

  • Java源码

  • JVM

  • 韩顺平

  • Java
  • Java
  • JavaWeb
  • 服务器软件
2023-04-17
目录

什么是服务器软件

# 00.什么是服务器软件

在学习JavaWeb开发之前,我们简单回顾下网络相关的概念  ‍

# Web相关概念回顾

‍

# 软件架构

目前软件架构主要分为2种:

  • C/S:客户端/服务器端,简单来说就是需要在客户/用户的电脑上安装软件后才能使用的,例如浏览器,VSCode,IDEA等工具,安装后才能使用这些软件。
  • B/S:浏览器/服务器端,简单来说就是在浏览器里访问的应用,不用安装特定的软件也可以使用,客户只需用浏览器访问网页即可使用,例如淘宝等电商网站,B站等视频网站,在浏览器里打开就能使用。

‍

目前流行的BS架构,好处在于:

  1. BS架构免安装,打开浏览器就能用,非常方便;
  2. 解决了兼容性问题,只要有浏览器,不管是Windows,Linux还是Mac电脑,都能访问得到。如果是CS架构,通常还需要对不同平台做兼容性处理(虽然目前有一些跨平台的计数,但兼容性处理还是有一定的麻烦)
  3. 更新快:如果是CS架构,有更新的话还需要用户下载更新包,或者安装包,然后才能更新。而如果是网页应用,用户不需要更新,刷新网页即可。

‍

当然CS架构也有优点,资源都是在本地的,打开速度快,方便离线使用。

‍

‍

# 资源分类

在BS架构中,用户访问的资源可以分为两类:

  • 静态资源:所有用户访问后,得到的结果都是一样的,称为静态资源。静态资源可以直接被浏览器解析,浏览器本身就有静态资源解析引擎。常见的静态资源: HTML,CSS和JavaScript
  • 动态资源:每个用户访问相同资源后,得到的结果可能不一样。称为动态资源。动态资源被访问后,需要先转换为静态资源,在返回给浏览器。如:Servlet,JSP,PHP,ASP等
  • 客户端请求资源(也叫请求,request),服务器返回资源(也叫响应,response)

举个例子,用户打开一个网站的登录页,所有用户的登录页都是一样的,所以登录页是一种静态资源,里面还包含了登录页的HTML、CSS和JS等静态资源;

用户登录后,每个用户的信息都是不同的,例如用户名不同,此时需要根据情况动态的展示网页,这样不同用户登录后,看到的东西才是不一样的,才是他们自己的。例如我登录自己的B站账号,显示的就是我的登录名

​​

‍

‍

根据用户请求的资源不同,请求可以划分为动态请求和静态请求。

‍

‍

‍

# 网络通信三要素

学习JavaWeb之前,读者应该对计算机网络有基本的概念,知道如下几个术语:

  • IP:电子设备(计算机)在网络中的唯一标识。

  • 端口:应用程序在计算机中的唯一标识。 0~65536

  • 传输协议:规定了数据传输的规则基础协议。例如两个人之间交流,使用的语言得一致,不然一个人说英文,一个人说中文,两者互相听不懂。基础的传输协议如下:

    • TCP:安全协议,三次握手,速度稍慢
    • UDP:不安全协议, 速度快
    • 应用层的传输协议,例如HTTP,IMAP等,都是基于上述协议的。

‍

‍

‍

‍

# 什么是服务器软件

服务器:安装了服务器软件的计算机。例如邮件服务器、web服务器,游戏服务器,MySQL服务器等等

服务器软件:运行后监听某个端口,接收用户的请求,处理请求,做出响应。例如邮件进程,游戏进程,MySQL进程等等。

Web服务器软件:接收用户的HTTP请求,处理请求,做出响应。在Web服务器软件中,可以部署Web项目,让用户通过浏览器来访问这些项目。

之前我们说的动态资源,就得依赖于Web服务器去运行,因此Web服务器软件也叫Web容器。

‍

HTTP服务器本质上也是一种应用程序,绑定服务器的IP地址并监听某一个TCP端口来接收并处理HTTP请求,这样客户端(一般来说是IE, Firefox,Chrome这样的浏览器)就能够通过HTTP协议来获取服务器上的网页(HTML格式)、文档(PDF格式)、音频(MP4格式)、视频(MOV格式)等等资源。下图描述的就是这一过程:

​​

‍

‍

# 自己实现服务器软件

我们来看一下如何编写HTTP Server。一个HTTP Server本质上是一个TCP服务器,我们先用TCP编程的多线程实现的服务器端框架:

public class Server {
    public static void main(String[] args) throws IOException {
        ServerSocket ss = new ServerSocket(8080); // 监听指定端口
        System.out.println("server is running...");
        for (;;) {
            Socket sock = ss.accept();
            System.out.println("connected from " + sock.getRemoteSocketAddress());
            Thread t = new Handler(sock);
            t.start();
        }
    }
}

class Handler extends Thread {
    Socket sock;

    public Handler(Socket sock) {
        this.sock = sock;
    }

    public void run() {
        try (InputStream input = this.sock.getInputStream()) {
            try (OutputStream output = this.sock.getOutputStream()) {
                handle(input, output);
            }
        } catch (Exception e) {
            try {
                this.sock.close();
            } catch (IOException ioe) {
            }
            System.out.println("client disconnected.");
        }
    }

    private void handle(InputStream input, OutputStream output) throws IOException {
        var reader = new BufferedReader(new InputStreamReader(input, StandardCharsets.UTF_8));
        var writer = new BufferedWriter(new OutputStreamWriter(output, StandardCharsets.UTF_8));
        // TODO: 处理HTTP请求
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40

只需要在handle()​方法中,用Reader读取HTTP请求,用Writer发送HTTP响应,即可实现一个最简单的HTTP服务器。编写代码如下:

private void handle(InputStream input, OutputStream output) throws IOException {
    System.out.println("Process new http request...");
    var reader = new BufferedReader(new InputStreamReader(input, StandardCharsets.UTF_8));
    var writer = new BufferedWriter(new OutputStreamWriter(output, StandardCharsets.UTF_8));
    // 读取HTTP请求:
    boolean requestOk = false;
    String first = reader.readLine();
    if (first.startsWith("GET / HTTP/1.")) {
        requestOk = true;
    }
    for (;;) {
        String header = reader.readLine();
        if (header.isEmpty()) { // 读取到空行时, HTTP Header读取完毕
            break;
        }
        System.out.println(header);
    }
    System.out.println(requestOk ? "Response OK" : "Response Error");
    if (!requestOk) {
        // 发送错误响应:
        writer.write("HTTP/1.0 404 Not Found\r\n");
        writer.write("Content-Length: 0\r\n");
        writer.write("\r\n");
        writer.flush();
    } else {
        // 发送成功响应:
        String data = "<html><body><h1>Hello, world!</h1></body></html>";
        int length = data.getBytes(StandardCharsets.UTF_8).length;
        writer.write("HTTP/1.0 200 OK\r\n");
        writer.write("Connection: close\r\n");
        writer.write("Content-Type: text/html\r\n");
        writer.write("Content-Length: " + length + "\r\n");
        writer.write("\r\n"); // 空行标识Header和Body的分隔
        writer.write(data);
        writer.flush();
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37

这里的核心代码是,先读取HTTP请求,这里我们只处理GET /​的请求。当读取到空行时,表示已读到连续两个\r\n​,说明请求结束,可以发送响应。

发送响应的时候,首先发送响应代码HTTP/1.0 200 OK​表示一个成功的200响应,使用HTTP/1.0​协议,然后,依次发送Header,发送完Header后,再发送一个空行标识Header结束,紧接着发送HTTP Body,在浏览器输入http://localhost:8080/​就可以看到响应页面:

​​

‍

可以看到编写一个简单的HTTP服务器并不难,只需要先编写基于多线程的TCP服务,然后在一个TCP连接中读取HTTP请求,发送HTTP响应即可。

但是,要编写一个完善的HTTP服务器,以HTTP/1.1为例,需要考虑的包括:

  • 识别正确和错误的HTTP请求;
  • 识别正确和错误的HTTP头;
  • 复用TCP连接;
  • 复用线程;
  • IO异常处理;
  • ...

这些基础工作需要耗费大量的时间,并且经过长期测试才能稳定运行。如果我们只需要输出一个简单的HTML页面,就不得不编写上千行底层代码,那就根本无法做到高效而可靠地开发。

因此,在JavaEE平台上,处理TCP连接,解析HTTP协议这些底层工作统统扔给现成的Web服务器去做,我们只需要把自己的应用程序跑在Web服务器上。

‍

# 常见的Web服务器软件

‍

开源且常见的:

  • Nginx:一款自由开源的、高性能的 HTTP 服务器和反向代理服务器,使用率较高。
  • Tengine:Tengine是阿里巴巴在Nginx的基础上,添加了很多高级功能和特性改造而成,做了一定的优化
  • Tomcat:归属于Apache基金组织,中小型的JavaEE服务器,开源免费。
  • Apache:非常老牌的WEB服务器,稳定、开源、跨平台,性能较Nginx低
  • Lighttpd:开源,CPU占用率低,内存开销小,也有不少人使用

‍

商业级且常见的:

  • WebShare:通常简称WAS,IBM公司开发的,大型的JavaEE服务器,支持所有的JavaEE规范,收费的。
  • WebLogic:Oracle公司开发的,大型的JavaEE服务器,支持所有的JavaEE规范,收费的。
  • JBOSS公司的,大型的JavaEE服务器,支持所有的JavaEE规范,收费的。

一般来说商业级的都是重量级的,安装包大、功能强大且繁多。一般得专人支持才能使用,因为是商业级的东西,网上也比较少入门的资料,毕竟是付费产品,如果想要自己学习的话比较难,因为文档资料不会公开,想要安装的话还得购买许可证,门槛高。

‍

‍

Apache 和 Nginx 本身不支持生成动态页面(不提供动态资源),但它们可以通过其他模块来支持(例如通过 Shell、PHP、Python 脚本程序来动态生成内容)。

如果想要使用 Java 程序来动态生成资源内容,使用这一类 HTTP 服务器很难做到。Java Servlet 技术以及衍生的 Java Server Pages 技术可以让 Java 程序也具有处理 HTTP 请求并且返回内容(由程序动态控制)的能力,Tomcat 正是支持运行 Servlet/JSP 应用程序的容器(Container)。后续我们就学习JavaWeb技术,使得Java可以开发一个网站并且发布。

‍

‍

本系列主要使用Nginx和Tomcat用于学习JavaWeb开发,这两个也是目前使用率比较高的。

‍

‍

‍

在GitHub上编辑此页 (opens new window)
上次更新: 2023/4/20 09:11:31
Java
Nginx介绍

← Java Nginx介绍→

Theme by Vdoing | Copyright © 2022-2023 粤ICP备2022067627号-1 粤公网安备 44011302003646号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式