Compare commits
10 Commits
28b73bcbf5
...
b85aac37da
Author | SHA1 | Date | |
---|---|---|---|
|
b85aac37da | ||
|
cd93db395c | ||
|
32d7edaa72 | ||
|
91705e2e30 | ||
|
f6721d69d4 | ||
|
f1238239c5 | ||
|
94f066d030 | ||
|
8d069c7770 | ||
|
4e739b1b36 | ||
|
4999937367 |
@ -12,7 +12,7 @@
|
||||
|
||||
#### 2. 可用性
|
||||
|
||||
可以性是指系统提供的服务必须一直处于可用状态,对于用户的每一个操作请求总是能够在有限的时间内返回结果。它主要强调以下两点:
|
||||
可用性是指系统提供的服务必须一直处于可用状态,对于用户的每一个操作请求总是能够在有限的时间内返回结果。它主要强调以下两点:
|
||||
|
||||
+ **有限的时间内**:对于用户的一个请求操作,系统必须要在指定的时间内返回处理结果,如果超过这个时间,那么系统就被认为是不可用的。
|
||||
+ **返回结果**:不论成功或者失败,都需要明确地返回响应结果。
|
||||
@ -79,4 +79,4 @@ BASE是对基本可用(Basically Available)、软状态( Soft State)、
|
||||
|
||||
## 参考资料
|
||||
|
||||
主要摘录自:倪超 . 从 Paxos 到 Zookeeper——分布式一致性原理与实践 . 电子工业出版社 . 2015-02-01
|
||||
主要摘录自:倪超 . 从 Paxos 到 Zookeeper——分布式一致性原理与实践 . 电子工业出版社 . 2015-02-01
|
||||
|
@ -28,10 +28,10 @@ JDK 从 1.8 版本开始支持 Lambda 表达式,通过 Lambda 表达式我们
|
||||
|
||||
Lambda 表达式具有如下特点:
|
||||
|
||||
- **可选的参数:**不需要声明参数类型,编译器会依靠上下文进行自动推断;
|
||||
- **可选的参数圆括号:**当且仅当只有一个参数时,包裹参数的圆括号可以省略;
|
||||
- **可选的花括号:**如果主体只有一个表达式,则无需使用花括号;
|
||||
- **可选的返回关键字:**如果主体只有一个表达式,则该表达式的值就是整个 Lambda 表达式的返回值,此时不需要使用 return 关键字进行显式的返回。
|
||||
- **可选的参数**:不需要声明参数类型,编译器会依靠上下文进行自动推断;
|
||||
- **可选的参数圆括号**:当且仅当只有一个参数时,包裹参数的圆括号可以省略;
|
||||
- **可选的花括号**:如果主体只有一个表达式,则无需使用花括号;
|
||||
- **可选的返回关键字**:如果主体只有一个表达式,则该表达式的值就是整个 Lambda 表达式的返回值,此时不需要使用 return 关键字进行显式的返回。
|
||||
|
||||
### 1.2 行为参数化
|
||||
|
||||
@ -148,7 +148,7 @@ public interface Function<T, R> {
|
||||
}
|
||||
```
|
||||
|
||||
**4. Predicate\<T>**:判断类型为 T 的变量是否满足特定的条件,如果满足则返回 true,否则返回 flase:
|
||||
**4. Predicate\<T>**:判断类型为 T 的变量是否满足特定的条件,如果满足则返回 true,否则返回 false:
|
||||
|
||||
```java
|
||||
@FunctionalInterface
|
||||
@ -206,7 +206,7 @@ JDK 1.8 中另一个大的改进是引入了流,通过流、Lamda 表达式以
|
||||
使用静态方法 `Stream.of()` 由指定的值进行创建:
|
||||
|
||||
```java
|
||||
Stream<String> stream = Stream.of("a", "b ", "c", "d");
|
||||
Stream<String> stream = Stream.of("a", "b", "c", "d");
|
||||
```
|
||||
|
||||
**2. 由集合或数组创建**
|
||||
@ -214,14 +214,14 @@ Stream<String> stream = Stream.of("a", "b ", "c", "d");
|
||||
使用静态方法 `Arrays.stream()` 由指定的数组进行创建:
|
||||
|
||||
```java
|
||||
String[] strings={"a", "b ", "c", "d"};
|
||||
String[] strings={"a", "b", "c", "d"};
|
||||
Stream<String> stream = Arrays.stream(strings);
|
||||
```
|
||||
|
||||
调用集合类的 `stream()` 方法进行创建:
|
||||
|
||||
```shell
|
||||
List<String> strings = Arrays.asList("a", "b ", "c", "d");
|
||||
List<String> strings = Arrays.asList("a", "b", "c", "d");
|
||||
Stream<String> stream = strings.stream();
|
||||
```
|
||||
|
||||
@ -516,4 +516,4 @@ stream.sequential();
|
||||
|
||||
## 参考资料
|
||||
|
||||
厄马(Raoul-Gabriel Urma) / 弗斯科(Mario Fusco) / 米克罗夫特(Alan Mycroft) .**《Java 8实战》**. 人民邮电出版社 . 2016-04-01
|
||||
厄马(Raoul-Gabriel Urma) / 弗斯科(Mario Fusco) / 米克罗夫特(Alan Mycroft) .**《Java 8实战》**. 人民邮电出版社 . 2016-04-01
|
||||
|
@ -512,7 +512,7 @@ JDK 9 之后为了适应模块化的发展,类加载器做了如下变化:
|
||||
### 7.1 编译器分类
|
||||
|
||||
+ **前端编译器**:把 `*.java` 文件转变成 `.class` 文件的过程;如 JDK 的 Javac,Eclipse JDT 中的增量式编译器。
|
||||
+ **即使编译器**:常称为 JIT 编译器(Just In Time Complier),在运行期把字节码转变成本地机器码的过程;如 HotSpot 虚拟机中的 C1、C2 编译器,Graal 编译器。
|
||||
+ **即时编译器**:常称为 JIT 编译器(Just In Time Complier),在运行期把字节码转变成本地机器码的过程;如 HotSpot 虚拟机中的 C1、C2 编译器,Graal 编译器。
|
||||
+ **提前编译器**:直接把程序编译成目标机器指令集相关的二进制代码的过程。如 JDK 的 jaotc,GUN Compiler for the Java(GCJ),Excelsior JET 。
|
||||
|
||||
### 7.2 解释器与编译器
|
||||
|
@ -285,7 +285,7 @@ InnoDB 存储引擎完全支持 ACID 模型:
|
||||
|
||||
**1.丢失更新**
|
||||
|
||||
一个事务的更新操作被另外一个事务的更新操作锁覆盖,从而导致数据不一致:
|
||||
一个事务的更新操作被另外一个事务的更新操作所覆盖,从而导致数据不一致:
|
||||
|
||||
<div align="center"> <img src="https://gitee.com/heibaiying/Full-Stack-Notes/raw/master/pictures/mysql-修改丢失.png"/> </div>
|
||||
|
||||
|
@ -90,7 +90,7 @@ Nginx 的配置文件支持以下空间和时间单位:
|
||||
|
||||
+ **空间单位**:不加任何单位默认就是 bytes,除此之外还支持 k/K,m/M,g/G 等常用单位。
|
||||
|
||||
+ **空间单位**:支持 ms (毫秒) ,s (秒) ,m (分钟) ,h (小时) ,d (天),w (星期),M (月,30天),y (年,365天) 等常用单位,并支持组合使用,如 `1h 30m` (1小时 30分),`1y 6M`(1年零6个月)。
|
||||
+ **时间单位**:支持 ms (毫秒) ,s (秒) ,m (分钟) ,h (小时) ,d (天),w (星期),M (月,30天),y (年,365天) 等常用单位,并支持组合使用,如 `1h 30m` (1小时 30分),`1y 6M`(1年零6个月)。
|
||||
|
||||
### 3.3 官方配置模板
|
||||
|
||||
|
@ -37,7 +37,7 @@ Tomcat 是目前主流的基于 Java 语言的轻量级应用服务器,它是
|
||||
|
||||
Tomcat 的整体架构如下:
|
||||
|
||||
<div align="center"> <img src="https://gitee.com/heibaiying/Full-Stack-Notes/raw/master/pictures\tomcat_架构.png"/> </div>
|
||||
<div align="center"> <img src="https://gitee.com/heibaiying/Full-Stack-Notes/raw/master/pictures/tomcat_架构.png"/> </div>
|
||||
|
||||
|
||||
+ **Server**:表示整个 Servlet 容器,在整个 Tomcat 运行环境中只有唯一一个 Server 实例。一个 Server 包含多个 Service,每个 Service 互相独立,但共享一个 JVM 以及系统类库。
|
||||
@ -56,7 +56,7 @@ Tomcat 的整体架构如下:
|
||||
|
||||
连接器的主要功能是将 Socket 的输入转换为 Request 对象,并交由容器进行处理;之后再将容器处理完成的 Response 对象写到输出流。连接器的内部组件如下:
|
||||
|
||||
<div align="center"> <img src="https://gitee.com/heibaiying/Full-Stack-Notes/raw/master/pictures\tomcat连接器组件.png"/> </div>
|
||||
<div align="center"> <img src="https://gitee.com/heibaiying/Full-Stack-Notes/raw/master/pictures/tomcat连接器组件.png"/> </div>
|
||||
|
||||
|
||||
### 3.1 ProtocolHandler
|
||||
@ -82,7 +82,7 @@ EndPoint 会启动线程来监听服务器端口,并负责处理来自客户
|
||||
|
||||
ProtocolHandler 通过组合不同类型的 Endpoint 和 Processor 来实现针对具体协议的处理功能。按照不同的协议(HTTP 和 AJP)和不同的 I/O 方式(NIO,NIO2,AJP)进行组合,其有以下六个具体的实现类:
|
||||
|
||||
<div align="center"> <img src="https://gitee.com/heibaiying/Full-Stack-Notes/raw/master/pictures\tomcat_AbstractProtocol.png"/> </div>
|
||||
<div align="center"> <img src="https://gitee.com/heibaiying/Full-Stack-Notes/raw/master/pictures/tomcat_AbstractProtocol.png"/> </div>
|
||||
|
||||
|
||||
**4. 协议升级**
|
||||
@ -93,7 +93,7 @@ ProtocolHandler 通过组合不同类型的 Endpoint 和 Processor 来实现针
|
||||
|
||||
Tomcat 设计者希望连接器是一个单独的组件,能够脱离 Servlet 规范而独立存在,以便增加其使用场景,因此 Process 对输入流封装后得到的 Request 不是一个 Servlet Request,该 Request 的全限定命名为:org.apache.coyote.Request 。因此在这里需要使用适配器模式(具体实现类是 CoyoteAdapter)将其转换为 org.apache.catalina.connector.Request,它才是标准的 ServletRequest 的实现:
|
||||
|
||||
<div align="center"> <img src="https://gitee.com/heibaiying/Full-Stack-Notes/raw/master/pictures\tomcat_request.png"/> </div>
|
||||
<div align="center"> <img src="https://gitee.com/heibaiying/Full-Stack-Notes/raw/master/pictures/tomcat_request.png"/> </div>
|
||||
|
||||
|
||||
### 3.3 Mapper 和 MapperListener
|
||||
@ -112,7 +112,7 @@ Tomcat 中的所有容器都实现了 Container 接口,它定义了容器共
|
||||
|
||||
|
||||
|
||||
<div align="center"> <img src="https://gitee.com/heibaiying/Full-Stack-Notes/raw/master/pictures\tomcat_container.png"/> </div>
|
||||
<div align="center"> <img src="https://gitee.com/heibaiying/Full-Stack-Notes/raw/master/pictures/tomcat_container.png"/> </div>
|
||||
|
||||
|
||||
|
||||
@ -126,7 +126,7 @@ Tomcat 之所以采用分层的结构,主要是为了更好的灵活性和可
|
||||
+ **Context**:表示一个具体的 Web 应用程序,一个虚拟主机可以包含多个 Context;
|
||||
+ **Wrapper**:是 Tomcat 对 Servlet 的包装,一个 Context 中可以有多个 Wrapper。
|
||||
|
||||
<div align="center"> <img src="https://gitee.com/heibaiying/Full-Stack-Notes/raw/master/pictures\tomcat_分层结构.png"/> </div>
|
||||
<div align="center"> <img src="https://gitee.com/heibaiying/Full-Stack-Notes/raw/master/pictures/tomcat_分层结构.png"/> </div>
|
||||
|
||||
|
||||
Tomcat 容器的分层结构在其 conf 目录下的 `server.xml` 配置文件中也有体现:
|
||||
@ -146,7 +146,7 @@ Tomcat 容器的分层结构在其 conf 目录下的 `server.xml` 配置文件
|
||||
|
||||
### 4.3 Pipeline 和 Valve
|
||||
|
||||
<div align="center"> <img src="https://gitee.com/heibaiying/Full-Stack-Notes/raw/master/pictures\tomcat_多层容器.jpg"/> </div>
|
||||
<div align="center"> <img src="https://gitee.com/heibaiying/Full-Stack-Notes/raw/master/pictures/tomcat_多层容器.jpg"/> </div>
|
||||
|
||||
|
||||
由连接器发过来的请求会最先发送到 Engine,最终逐层传递,直至我们编写的 Servlet,这种传递主要通过 Pipeline 和 Valve 来实现。每层容器都有自己的 Pipeline,Pipeline 相当于处理管道;每个 Pipeline 中有一个 Valve 链,每个 Valve 可以看做一个独立的处理单元,用于对请求进行处理。最基础的 Valve 叫做 Basic Valve,新增的 Valve 会位于已有的 Valve 之前。Pipeline 和 Valve 的接口定义如下:
|
||||
@ -284,14 +284,14 @@ protected void service(HttpServletRequest req, HttpServletResponse resp) throws
|
||||
|
||||
这里对前面的连接器和容器章节进行总结,Tomcat 对客户端请求的完整处理流程如下:
|
||||
|
||||
<div align="center"> <img src="https://gitee.com/heibaiying/Full-Stack-Notes/raw/master/pictures\tomcat启动请求处理流程.jpg"/> </div>
|
||||
<div align="center"> <img src="https://gitee.com/heibaiying/Full-Stack-Notes/raw/master/pictures/tomcat启动请求处理流程.jpg"/> </div>
|
||||
|
||||
|
||||
## 六、启动流程
|
||||
|
||||
Tomcat 整体的启动流程如下图所示:
|
||||
|
||||
<div align="center"> <img src="https://gitee.com/heibaiying/Full-Stack-Notes/raw/master/pictures\tomcat启动流程.png"/> </div>
|
||||
<div align="center"> <img src="https://gitee.com/heibaiying/Full-Stack-Notes/raw/master/pictures/tomcat启动流程.png"/> </div>
|
||||
|
||||
|
||||
|
||||
@ -314,7 +314,7 @@ Catalina 通过 Digester 解析 server.xml 来创建所有的服务组件。Dige
|
||||
|
||||
Tomcat 并没有完全沿用 JVM 默认的类加载机制,为了保证 Web 应用之间的隔离性和加载的灵活性,其采用了下图所示的类加载机制:
|
||||
|
||||
<div align="center"> <img width="600px" src="https://gitee.com/heibaiying/Full-Stack-Notes/raw/master/pictures\tomcat_类加载器.jpg"/> </div>
|
||||
<div align="center"> <img width="600px" src="https://gitee.com/heibaiying/Full-Stack-Notes/raw/master/pictures/tomcat_类加载器.jpg"/> </div>
|
||||
|
||||
|
||||
#### 1. Web App Class Loader
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 9.1 KiB After Width: | Height: | Size: 15 KiB |
Loading…
x
Reference in New Issue
Block a user