jev-trader 简介

jev-trader 是由 Monad 基金会首席AI工程师 Jarrod Watts 开源的AI做市/高频交易机器人,基于 TypeSafe AI 推出的Jev(TypeSafe System One)快速决策模型开发,是Jev模型出圈的首个标杆Demo项目。 基础信息 GitHub:jarrodwatts/jev-trader,Bun + TypeScript 开发 交易标的:Monad 链上 Kuru 交易所 MON/USDC 演示页面:jev-trader.vercel.app,提供可视化实时仪表盘,展示盘口、模型置信度、成交记录 核心机制 决策层:Jev模型 Jev 不是大语言模型,主打低延迟实时决策,目标适配Monad约300ms的出块间隔;读取订单簿数据后输出:买/卖/持有 + 置信概率,只给出交易判断,不生成文本。 执行层:做市限价单 程序拿到Jev的判断后,在盘口价差内侧挂仅成交限价单(post-only),赚取买卖价差,属于简单链上做市策略。 两种运行模式 Dry-run(默认空跑):只看盘、做模拟决策,不真实下单,适合调试观察 实盘模式:导入私钥后才会发链上交易 项目定位(重点) 作者明确强调:这只是技术演示Demo,不是稳赚交易策略,目的是证明Jev模型可以跟上Monad的高速出块节奏,适合AI决策+链上交易的学习、二次开发,不适合直接拿来盈利。 社区情况与风险 开源后衍生出很多分支版本:比如移植到Hyperliquid的jev-trade,支持BTC/ETH/SOL等合约多空 社区有实盘测试案例,出现过短时间大额亏损;AI高置信度≠盈利,缺少成熟回测、风控,市场波动下容易反复频繁换向、持续亏损 简单区分 Jev:TypeSafe AI的快速决策模型(System One) jev-trader:用Jev模型写的Monad链上做市机器人Demo

2026-10-11

数字货币交易所-gateio

Gate.io芝麻开门创立于2013年,是全球真实交易量TOP10的数字资产交易平台。 作为全球首家提供100%保证金审计证明的交易所,Gate.io在全球多个国家进行合法注册,向全球数千万用户提供安全可靠、真实透明的数字资产交易服务。 使用下面的链接注册,可以获得平台的奖励 https://www.gatewebsite.app/share/HAOKIUXX/ 或者使用gate的邀请码:HAOKIUXX

2023-06-24

enkrypt invite code FC433A

The enkrypt invite code is FC433A Mint tickets with Enkrypt every day, invite friends to earn more tickets. More tickets — more chances to win! Share your code with friends and get +1 ticket for every friend’s mint. Code FC433A address:https://raffle.enkrypt.com

2023-05-21

googo 邀请码 lbVOQjeS

googo 可以让你更好的浏览外文网站,比如meta、youtube,google等。 它之前的网址是googo.in,现在已经不用访问。是一款非常好用的科学上网工具,使用简单。 使用这个链接可以获取优惠:https://cn.googo.us/#/register?code=lbVOQjeS 或者使用这个邀请码:lbVOQjeS

2023-03-18

Hobert读书笔记

第一章 并发编程的挑战第2章 InnoDB存储引擎第1章 Java的I/O演进之路第1章 Spring框架的由来第2章 Tomcat总体架构三、Paxos的工程实践序第1章 概述第6章 深入分析ClassLoader工作机制第8章 虚拟机字节码执行系统

2021-06-08

第1章 Java的I/O演进之路

第1章 Java的I/O演进之路 1.1 I/O基础入门 1.1.1 Linux网络I/O模型简介 UNIX提供了5种I/O模型: (1)阻塞I/O模型 (2)非阻塞I/O模型 (3)I/O复用模型 (4)信号驱动I/O模型 (5)异步I/O 1.1.2 I/O多路复用技术 把多个I/O阻塞复用到同一个select的阻塞上,从而是的系统在单线程的情况下可以同时处理多个客户端请求。比多线程有性能优势,节约资源。 支持I/O多路复用的系统调用select/pselect/poll/epoll。 epoll的优点: 支持一个进程打开的socket描述符(FD)不受限制(仅受限于操作系统的最大文件句柄数(内存))。 I/O效率不会随着FD数目的增加而线性下降。 使用mmap加速内核与用户空间的消息传递。 epoll的API更加简单。 1.2 Java的I/O演进 历史题,略。 第2章 NIO入门 2.1 传统的BIO编程 C/S模型,客户端发起连接请求,三次握手,通过Socket进行通信。 2.1.1 BIO通信模型图 一请求一应答模型:每次接收到连接请求都创建一个新的线程进行链路处理。处理完成后通过输出流返回应答给客户端,线程销毁。 该模型最大的问题就是:缺乏弹性伸缩能力,当客户端并发访问量增加后,服务端的线程个数和客户端并发访问数呈1:1的正比关系。 2.1.2 同步阻塞式I/O创建的TimeServer源码分析 import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; /** * <p>Description: 同步阻塞式I/O创建的TimeServer</p> * * @author 李宏博 * @version xxx * @create 2019/8/14 17:58 */ public class TimeServer { /** * * @param args */ public static void main(String[] args) throws IOException { int port = 8080; if (args != null && args.length > 0) { try { port = Integer.valueOf(args[0]); } catch (NumberFormatException e) { e.printStackTrace(); } } ServerSocket server = null; try { server = new ServerSocket(port); System.out.println("服务端端口开启:" + port); Socket socket = null; while (true) { socket = server.accept(); new Thread(new TimeServerHandle(socket)).start(); } } finally { if (server != null) { System.out.println("服务端关闭"); server.close(); server = null; } } } } import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.Socket; /** * <p>Description: xx</p> * * @author 李宏博 * @version xxx * @create 2019/8/14 18:05 */ public class TimeServerHandle implements Runnable { private Socket socket; public TimeServerHandle(Socket socket) { this.socket = socket; } @Override public void run() { BufferedReader in = null; PrintWriter out = null; try { in = new BufferedReader(new InputStreamReader(this.socket.getInputStream())); out = new PrintWriter(this.socket.getOutputStream(),true); String currentTime = null; String body = null; while (true) { body = in.readLine(); if (body == null) { break; } System.out.println("接收到命令:" + body); currentTime = "time".equalsIgnoreCase(body) ? new java.util.Date(System.currentTimeMillis()).toString() : "命令错误"; out.println(currentTime); } } catch (Exception e) { if (in != null) { try { in.close(); } catch (IOException ex) { ex.printStackTrace(); } } if (out != null) { out.close(); out = null; } if (this.socket != null) { try { this.socket.close(); } catch (IOException ex) { ex.printStackTrace(); } finally { this.socket = null; } } } } } 2.1.3 同步阻塞式I/O创建的TimeClient源码分析 import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.Socket; import java.net.UnknownHostException; /** * <p>Description: 同步阻塞式I/O创建的TimeClient</p> * * @author 李宏博 * @version xxx * @create 2019/8/14 18:21 */ public class TimeClient { /** * * @param args */ public static void main(String[] args) { int port = 8080; if (args != null && args.length > 0) { try { port = Integer.valueOf(args[0]); } catch (NumberFormatException e) { e.printStackTrace(); } } Socket socket = null; BufferedReader in = null; PrintWriter out = null; try { socket = new Socket("127.0.0.1",port); in = new BufferedReader(new InputStreamReader(socket.getInputStream())); out = new PrintWriter(socket.getOutputStream(),true); out.println("time"); System.out.println("命令发送成功"); String resp = in.readLine(); System.out.println("现在时间:" + resp); } catch (UnknownHostException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { if (out != null) { out.close(); out = null; } if (in != null) { try { in.close(); } catch (IOException e) { e.printStackTrace(); } finally { in = null; } } if (socket != null) { try { socket.close(); } catch (IOException e) { e.printStackTrace(); } finally { socket = null; } } } } } 2.2 伪异步I/O编程 引入线程池。 ...

2021-06-08

第1章 Spring框架的由来

第1章 Spring框架的由来 1.1 Spring之崛起 1.2 Spring框架概述 基于POJO(Plain Old Java Object,简单Java对象)的轻量级开发理念。 Spring总体架构: 1.3 Spring大观园 1.4 小结 第2章 Spring的IOC容器 2.1 我们的理念是:让别人为你服务 2.2 手语,呼喊,还是心有灵犀 2.2.1 构造方法注入 IoC Service Provider会检查被注入对象的构造方法,取得它所需要的依赖对象列表,进而为其注 入相应的对象。同一个对象是不可能被构造两次的,因此,被注入对象的构造乃至其整个生命周期, 应该是由IoC Service Provider来管理的。 2.2.2 setter方法注入 setter方法注入虽不像构造方法注入那样,让对象构造完成后即可使用,但相对来说更宽松一些, 可以在对象构造完成后再注入。 2.2.3 接口注入 对于前两种注入方式来说,接口注入没有那么简单明了。被注入对象如果想要IoC Service Provider为其注入依赖对象,就必须实现某个接口。这个接口提供一个方法,用来为其注入依赖对象。 IoC Service Provider最终通过这些接口来了解应该为被注入对象注入什么依赖对象。 示例: 2.2.4 三种注入方式的比较 接口注入。不提倡,带有侵入性 构造方法注入。这种注入方式的优点就是,对象在构造完成之后,即已进入就绪状态,可以马上使用。缺点就是,当依赖对象比较多的时候,构造方法的参数列表会比较长。而通过反射构造对象的时候,对相同类型的参数的处理会比较困难,维护和使用上也比较麻烦。而且在Java中,构造方法无法被继承,无法设置默认值。对于非必须的依赖处理,可能需要引入多个构造方法,而参数数量的变动可能造成维护上的不便。 setter方法注入。因为方法可以命名, 所以setter方法注入在描述性上要比构造方法注入好一些。另外, setter方法可以被继承,允许设置默认值,而且有良好的IDE支持。缺点当然就是对象无法在构造完成后马上进入就绪状态。 2.3 IOC的附加值

2021-06-08

第1章 概述

第1章 概述 互联网公司的分布式两个特点:规模大、成本低。 1.1 分布式存储概念 定义:分布式存储系统是大量普通PC服务器通过Internet互联,对外作为一个整体提供存储服务。 特性: 可扩展。集群,性能随规模线性增长。 低成本。有自动容错,自动负载均衡机制。所以可以构建在普通PC机器。 高性能。 易用。提供易用的对外接口。 主要挑战:数据、状态信息的持久化,要求在自动迁移、自动容错、并发读写的过程中保证数据的一致性。 主要技术来自于分布式系统和数据库: 数据分布:如何保证均匀?如何实现跨服务器读写? 一致性:如何复制?如何保证出现异常也一致? 容错:如何检测?出错如何迁移? 负载均衡:如何实现?如何做到迁移时不影响其他业务? 事务与并发控制:如何实现分布式事务?如何实现MVCC? 易用性:如何易用?如何方便运维? 压缩/解压缩:如何根据数据特点设计压缩/解压缩算法?如何平衡节省的存储空间和消耗的CPU资源浪费? 1.2 分布式存储分类 数据大致分为三类: 非结构化数据:包括所有格式的办公文档、文本、图片、图像、音频和视频信息等。 结构化数据:一般存储在关系数据库中,可用二位关系表结构来表示。 半结构化数据:与结构化的区别在于,半结构化数据的模式结构和内容混在一起,没有明显的区分,也不需要预先定义数据的模式结构。 存储系统分为四类: 分布式文件系统 图片、照片、视频等非结构化数据对象,以对象组织,对象之间没有关联,称为Blob(Binary Large Object,二进制大对象)数据。 总体上看:分布式文件系统存储三种类型的数据:Blob对象、定长块以及大文件。在系统层面,分布式文件系统内部按照数据块来组织数据,每个数据块的大小大致相同,每个数据块可以包含多个Blob对象或者定长块,一个大文件也可以拆分成多个数据块。 分布式键值系统 用于存储关系简单的半结构化数据,它只提供基于主键的CRUD功能,即根据主键创建、读取、更新或者删除一条键值记录。 与传统哈希表相似,但是支持将数据分布到多个存储节点。 分布式键值系统是分布式表格系统的一种简化实现,一般用作缓存。 分布式表格系统 用于存储较为复杂的半结构化数据。不仅仅支持简单的CRUD操作,而且支持扫面某个主键范围。 借鉴了许多关系型数据库的技术,例如支持某种程度上的事务,比如单行事务,某个实体组下的多行事务。 与分布式数据库先比,仅支持针对单张表格的操作,不支持复杂操作。 分布式数据库 一般从单机数据库扩展而来,用于存储结构化数据。 第2章 单机存储系统 单机存储引擎就是哈希表、B树等数据结构在机械磁盘、SSD等持久化介质上的实现。 2.1 硬件基础 2.1.1 CPU架构 经典的多CPU架构为对称多处理结构(Symmetric Multi-Processing,SMP),即在一个计算机上汇集了一组处理器,它们之间对称工作,无主次或从属关系,共享相同的物理内存及总线。 2.1.2 IO总线 存储系统的性能瓶颈一般在与IO。 2.1.3 网络拓扑 传统的数据中心网络拓扑,分三层。最下面是接入层,中间是汇聚层,上面是汇聚层。存在的问题:大量下层接入,导致同一个接入层下的服务器之间的带宽减小。 2.1.4 性能参数 2.1.5 存储层次架构 存储系统的性能主要包括两个维度:吞吐量以及访问延时。 2.2 单机存储引擎 2.2.1 哈希存储引擎 Bitcask是一个基于哈希表结构的键值寸尺系统,它仅支持追加操作(Append-only),即所有的写操作只追加而不修改老的数据。 在Bitcask系统中,每个文件有一定的大小限制,当文件增加到相应的大小时,就会产生一个新的文件,老的文件只读不写。在任意时刻,只有一个文件市可写的,用于数据追加,称为活跃数据文件。而其他已经达到大小限制的文件,称为老数据文件。 数据结构 一条一条写入,每条记录的数据项分别为:主键(key),value内容(value),主键长度(key_sz),value长度(value_sz),时间戳(timetamp)以及crc校验值。(删除不会删除旧的条目,而是将value设定为一个特殊的之作标识)。内存中的结构是hash表。 定期合并 为解决垃圾文件问题。将所有老数据文件中的数据扫描一遍生成一个新的数据文件。对用一个key的多个操作以保留最新的一个原则进行删除。 快速恢复 每次合并时,将内存中的哈希索引表转储到磁盘中,生成一个索引文件。这个索引文件只存储value的位置。 2.2.2 B树存储引擎 不仅支持随机读取,还支持范围扫描。 数据结构 InnoDB按照页面(Page)来组织数据,每个页面对用B+树的一个节点。 B+树的根节点是常驻内存的。修改操作首先需要记录提交日志,接着修改内存中的B+树。 缓冲区管理 LRU、LIRS 2.2.3 LSM树存储引擎 将对数据的修改增量保持在内存中,达到指定的大小先之后将这些修改操作批量写入磁盘,读取时需要合并磁盘中的历史数据和内存中最近的修改操作。

2021-06-08

第2章 InnoDB存储引擎

第2章 InnoDB存储引擎 事务安全。 2.1 InnoDB存储引擎概述 Mysql5.5开始是默认的表存储引擎(之前尽在Window下是)。第一个完整支持ACID事务的MySQL存储引擎。其特点是行锁设计、支持MVCC、支持外键、提供一致性非锁定读,同时被设计用来最有效地利用以及使用内存和CUP。 高性能、高可用、高扩展。 2.2 InnoDB存储引擎的版本 略 2.3 InnoDB体系结构 后台线程的主要作用是负责刷新内存池中的数据,保证缓冲池中的内存缓存的是最近的数据。 此外将已修改的数据文件刷新到磁盘文件,同时保证在数据库发生异常的情况下InnoDB能恢复到正常运行状态。 2.3.1 后台线程 多线程模型。不同的后台线程处理不同的任务。 Master Thread 将缓冲池的数据异步刷新到磁盘,保证数据一致性,包括脏页的刷新、合并插入缓冲(INSERT BUFFER)、UNDO页的回收。 IO Thread 大量使用AIO(Async IO),极大提高性能。IO Thread主要负责这些IO请求的回调处理。 第3章 文件 参数文件:告诉MySQL启动时查找文件的地址,指定初始化参数; 日志文件:错误日志文件、二进制文件日志文件、慢查询日志文件、查询日志文件; socket:当用UNIX域套接字方式进行连接时需要的文件 pid文件:MySQL实例的进程ID文件 MySQL表结构文件:用来存放MySQL表结构定义文件 存储引擎文件:每个存储引擎都会有自己的文件来保存各种数据,这些存储引擎真正存储了记录和索引等数据。 3.1 参数文件 MySQL实例也可以不需要参数文件,这是编译MySQL时指定的默认值。但是如果在默认的数据库目录下找不到mysql架构,则会启动失败。 3.1.1 什么是参数 数据库中的参数是键值对。MySQL中无类似Oracle中的隐藏参数。 3.1.2 参数类型 动态参数:运行时可修改 静态参数:在整个实例的生命周期都不能修改。 3.2 日志文件 日志文件记录了MySQL数据库的各种类型活动。 3.2.1 错误日志 对MySQL的启动、运行、关闭过程进行了记录。当出现MySQL数据库不能正常启动时,第一个必须查找的文件应该就是错误日志文件。 3.2.2 慢查询日志 帮助DBA定位可能存在问题的SOL语句,从而进行SQL语句层面的优化。设置一个阈值(最小精度是微秒),超过(必须是大于,等于不行)时将该SQL语句记录到慢查询日志中。 默认情况下并不启动慢查询日志。 如果没有使用索引也会被记录。 3.2.3 查询日志 记录了所有对MySQL数据库请求的信息,无论这些请求是否得到了正确的执行。 3.2.4 二进制文件 记录了对MySQL数据库执行更改的所有操作,但是不包括SELEC和SHOW这类操作。 作用: 恢复:某些数据的恢复需要二进制日志。 复制:主从复制 审计:通过审计二进制文件,判断是否有数据库进行注入的攻击。 二进制日志文件在默认情况下并没有启动,需要手动指定参数来启动。会影响性能,但仅仅1%。 缓冲写宕机问题,无缓冲写宕机问题 3.3 套接字文件 3.4 pid文件 3.5 表结构定义文件 记录该存储引擎对应的表结构 3.6 InnoDB存储引擎文件 InnoDB独有的文件 3.6.1 表空间文件 InnoDB采用将存储的数据按表空间进行存放的设计。 还可设置独立表空间,用户不用将所有数据都存放于默认的表空间中。 单独的表空间仅存储表的数据、索引和插入缓冲BITMAP等信息,其余的信息存放到默认表空间。 3.6.2 重做日志文件 宕机问题。 重做日志文件与二进制文件的区别: 记录范围,二进制日志会记录所有与MySQL数据库有关的日志记录,而InnoDB仅记录该存储引擎的事务日志。 记录内容,二进制日志记录具体操作(逻辑日志),而InnoDB的重做日志文件是关于每个Page的更改的物理情况 写入时间,二进制日志文件只在事务提交前进行一次写入,而重做日志文件在事务的进行过程中,一直会被写入。 3.7 小结 重做日志文件使得InnoDB存储引擎可以提供可靠的事务。 第4章 表 4.1 索引组织表 在InnoDB存储引擎中,表都是根据主键顺序组织存放。 在InnoDB存储引擎中,每张表都有个主键,如果没有显示定义,则按如下方式创建: 首先判断表中是否含有唯一非空索引(Unique NOT NULL),如果有,则该列即为主键。(按定义索引的顺序选择) 如果不符合上述条件,InnoDB存储引擎自动创建一个6字节大小的指针。 _rowid仅适用于单个列为主键的情况。 ...

2021-06-08

第2章 Tomcat总体架构

第2章 Tomcat总体架构 系统设计及中间件设计时的参考:生命周期管理、可扩展的容器组件设计、类加载方式。 2.1 总体设计 如何设计一个应用服务器? 2.1.1 Server 最基本的功能:接收请求,业务处理,返回响应。 两个方法: start():启动服务器,打开Socket链接,监听端口,负责接收请求,处理及返回。 stop():停止服务器并释放网络资源。 作为嵌入在应用系统中的远程请求处理方案,且访问量低时可行。但作为应用服务器不可行。 2.1.2 Connector和Container 请求监听与请求处理放到一起扩展性差。 Connector负责监听,返回。 Container负责处理请求。 均分别拥有自己的start()和stop()方法来加载和释放自己维护的资源。 明显的缺陷:如何让Connector与Container对应?可以维护一个复杂关系映射,但是并不必需。Container设计足够灵活。 引入Service,负责维护多个Connector和一个Container。 在Tomcat中,Container是一个更加通用的概念。为了与Tomcat中的组件命名一致,所以重新命名为Engine,用以表示整个Servlet引擎。 Engine表示整个Servlet引擎。Server表示整个Servlet容器。 2.1.3 Container设计 应用服务器是用来部署并运行Web应用的,是一个运行环境,而不是独立的业务处理系统。因此需要在Engine容器中支持管理Web应用,当接收到Connector的处理请求时,Engine容器能够找到一个合适的Web应用来处理。 使用一个Context来表示一个Web应用,并且一个Engine可以包含多个Context。 虚拟主机,加入Host。一个Host可以包含多个Context。 Tomcat的设计中Engine可以包含Host也可以包含Context,这是由具体的Engine实现确定的。Tomcat提供的默认实现StandardEngine只能包含Host。 一个Web应用可以包含多个Servlet实例。在Tomcat中,Servlet定义被称为Wrapper。 “容器”的作用都是处理请求并返回响应数据。所以引入一个Container接口:addchild()添加子容器,backgroundProcess()实现文件变更的扫描。 2.1.4 Lifecycle 所有组件均存在启动、停止这两个生命周期方法,可在此基础上扩展生命周期管理的方法,即对于生命周期管理进行一次接口抽象。 将Server接口替换为Lifecycle接口: Init():初始化组件 start():启动组件 stop():停止组件 destory():销毁组件 addLifecycleListener:添加事件监听器(用于监听组件的状态变化) removeLifecycleListener:删除 Tomcat核心组件的默认实现均继承自LifecycleBeanBase抽象类,该类不但负责组件各个状态的转换和事件处理,还将组件自身注册为MBean,以便通过Tomcat的管理工具进行动态维护。 2.1.5 Pipeline和Valve 以上设计以保证核心架构的了可伸缩性和可扩展性。但是还要考虑各个组件的灵活性,使其同样可扩展。 责任链模式是一种比较好的选择。Tomcat即采用该模式来实现客户端请求的处理。在Tomcat中每个Container组件通过执行一个责任链来完成具体的请求处理。 Pipeline(管道)用于构造责任链,Valve(阀)代表责任链上的每个处理器。Pipeline中维护了一个基础的Valve(位于末端,最后执行)。 Tomcat的每个层级的容器(Engine、Host、Context、Wrapper)均有对应的基础Valve实现,同时维护一个Pipeline实例。即任何层级的容器都可以对请求处理进行可扩展。 2.1.6 Connector设计 基本功能: 监听服务器端口,读取来自客户端的请求。 将请求数据按照指定协议进行解析。 根据请求地址匹配正确的容器进行处理。 将响应返回客户端。 Tomcat支持多协议,默认支持HTTP和AJP。同时支持多种I/O方式,包括BIO(8.5之后移除)、NIO、APR。而且在Tomcat8之后新增了对NIO2和HTTP/2协议的支持。因此对协议和I/O进行抽象和建模时需要关注的重点。 在Tomcat中,ProtocolHandler表示一个协议处理器,其包含一个Endpoint(无此接口,仅有AbstractEndpoint抽象类)用于启动Socket监听,还包含一个Processor用于按照指定协议读取数据,并将请求交由容器处理。 在Connector启动时,Endpoint会启动线程来监听,并在接收到请求后调用Processor进行数据读取。 当Processor读取客户端请求后,需要按照请求地址映射到具体的容器进行处理,这个过程即为请求映射。由于Tomcat各个组件采用通用的生命周期管理,而且可以通过管理工具进行状态变更,因此请求映射除考虑映射规则的实现外,还要考虑容器组件的注册与销毁。 Tomcat通过Mapper和MapperListener两个类实现上述功能。前者用于维护容器映射信息,同时按照映射规则(Servlet规范)查找容器。后者实现了ContainerListener和LifecycleListener,用于在容器组件状态发生变更时,注册或者取消对应的容器映射信息。为了实现上述功能,MapperListener实现了Lifecycle接口,当其启动时(在Service启动时启动),会自动作为监听器注册到各个容器组件上,同时将已创建的容器注册到Mapper。 Tomcat通过适配器模式(Adapter)实现了Connector与Mapper、Container的解耦。实现自己的Adapter可以脱离Servlet容器又使用Tomcat链接器。 2.1.7 Excutor 并发问题的解决方案。采用线程池(默认采用JDK5的线程池,继承自Lifecycle,当作通用组件进行管理)对线程进行统一管理。 在Tomcat中Excutor由Service维护,因此同一个Service中的组件可以共享一个线程池。 如果没有定义任何线程池,相关组件(Endpoint)会自动创建线程池,此时线程池不再共享。 在Tomcat中,Endpoint会启动一组线程来监听Socket端口,当接收到客户端请求后,会创建请求处理对象,并交由线程池处理,由此支持并发处理客户端请求。 2.1.8 Bootstrap和Catalina 除开前面的核心组件外,还需要提供一套配置环境来支持系统的可配置性,便于通过修改配置来优化应用。 集群、安全等组件同样重要,但不属于通用概念。 Tomcat通过类Catalina提供了一个Shell程序,用于解析server.xml创建各种组件,同时,负责启动、停止应用服务器(只需要启动Tomcat顶层组件Server)。 Tomcat使用Digester解析XML文件,包括server.xml以及web.xml等。 最后,Tomcat提供了Bootstrap作为应用服务器启动入口。Bootstrap负责创建Catalina实例,根据执行参数调用Catalina相关方法完成针对应用服务器的操作(启动、停止)。 Bootstrap与Tomcat应用服务器完全松耦合(通过反射调用Catalina实例),它可以直接依赖JRE运行并为Tomcat应用服务器创建共享类加载器,用于构造Catalina实例以及整个Tomcat服务器。 上述是Tomcat标准的启动方式。但是Server及其子组件代表了应用服务器本身,那么我们可以不通过Bootstrap和Catalina来启动服务器。 Tomcat组件说明: 组件名称 说明 Server 表示整个Servlet容器,因此Tomcat运行环境中只有唯一一个Server实例 Service Service表示一个或者多个Connector的集合,这些Connector共享同一个Container来处理其请求。在同一个Tomcat实例内可以包含任意多个Service实例,它们彼此独立 Connector 即Tomcat链接器,用于监听并转化Socket请求,同时将读取的Socket请求交由Container处理,支持不同协议以及不同的I/O方式 Container Container表示能够执行客户端请求并返回响应的一类对象。在Tomcat中存在不同级别的容器:Engine、Host、Context、Warpper Engine Engine表示整个Servlet引擎。在Tomcat中,Engine为最高层级的容器对象。尽管Engine不是直接处理请求的容器,确实获取目标容器的入口 Host Hostz作为一类容器,表示Servlet容器中的虚拟机,与一个服务器的网络名有关,如域名等。客户端可以使用这个网络名连接服务器,这个名称必须在DNS服务器上注册。 Context Context作为一类容器,用于表示ServletContext,在Servlet规范中,一个ServletContext即表示一个独立的Web应用 Wrapper Wrapper作为一类容器,用于表示Web应用中动议的Servlet Executor 表示Tomcat组件可以共享的线程池 2.2 Tomcat启动 Tomcat默认实现在相关概念的基础上结合生命周期管理监听器完成了大量的启动工作。 ...

2021-06-08