项目经历.md
概述
在参与 医疗云软件系统 的项目中,我的主要职责是构建和优化医疗档案管理系统,客户包括广州市和深圳市的几家大型医疗机构,主要以广医三院为首。以下是项目的详细描述和我在其中的具体贡献:
项目背景
该系统的主要目标是为大型医疗机构搭建一套 高效、安全的医疗档案管理系统。项目使用了母公司自研的服务器和超融合操作系统,同时通过 网络专线 来确保数据传输的安全性和稳定性。系统分为多个模块,涵盖了 底层文件存储、元数据存储、后台监控、档案上传客户端 和 前台查看 等。
技术选型与架构设计
Reactor 设计模式的优化
在接收文件元数据服务的请求时,我采用了 Reactor 设计模式,优化了元数据服务的并发处理能力。通过异步事件驱动的设计,减少了同步处理中的线程阻塞,提高了元数据请求的吞吐量和响应速度。MySQL 数据库的优化
我深入分析了 MySQL 的性能瓶颈,针对客户的高并发和大量数据读写需求,对 MySQL 的 启动配置参数 进行了调优,优化了缓存、连接池等配置,提升了数据库的整体性能。搭建 MySQL MGR 实现读写分离
为了进一步优化服务响应速度,我们采用了 MySQL MGR(MySQL Group Replication) 实现了 读写分离。读写分离的设计使得系统在数据查询和写入时能够分配到不同的节点,提升了服务的可扩展性和高可用性。医疗数据上链
根据客户的需求,我们进行了以太坊私有链的搭建,确保部分重要的医疗档案数据能够以 不可篡改 的形式记录在区块链上。在技术实现方面,我使用 Geth 来搭建以太坊私有链,并通过 Solidity 编写了智能合约。我们还使用 web3.py 提供了数据上链的服务接口,实现了档案上传后自动进行哈希记录的功能。
项目挑战与成果
在项目的开发过程中,我们面临的一个主要挑战是如何在 高并发请求 和 海量数据读写 场景下保持系统的 高效运行。为此,我深入研究并优化了元数据服务的并发处理架构,并采用了 MySQL MGR 进行读写分离,解决了数据查询和写入冲突的问题。
最终,我们成功交付了这个医疗档案管理系统,并且得到了客户的高度认可。系统实现了 高效的文件存储与快速检索,并通过区块链的应用提升了数据的安全性和可信度。
项目收获
这次项目经历让我在 分布式系统架构、数据库优化、区块链应用 等方面有了更深入的理解,同时也锻炼了我在高并发处理和数据一致性保证上的能力。
这个项目的成功,不仅帮助客户提升了档案管理的效率和安全性,同时也积累了许多宝贵的经验。希望这个回顾能够充分展现我的项目经历和技术能力。
技术栈
医疗数据上链是指将医疗数据的关键信息(如医疗档案的哈希值、操作记录等)通过区块链技术记录下来,确保数据的 不可篡改性 和 安全性。这种方式能够增强数据的可信度,并为医疗机构提供透明的数据管理方案。
医疗数据上链的业务动作
生成医疗数据的哈希
在用户上传医疗档案或记录后,系统首先对上传的医疗文件或数据生成一个唯一的哈希值(如使用 SHA-256 哈希算法)。这个哈希值是医疗文件的唯一标识,用于确保文件的完整性和不可篡改性。- 业务动作:客户端将用户上传的医疗档案进行本地或服务端计算,生成文件的哈希值。
- 实现方式:通过 Python 或其他编程语言使用加密库,如
hashlib
,对文件内容进行哈希计算。
打包关键信息
系统会将医疗档案的哈希值、时间戳、上传者 ID 以及其他关键信息打包成一个 JSON 对象或数据结构,准备作为智能合约的数据输入。这个信息包保证了上链数据的唯一性和完整性。- 业务动作:系统将计算得出的哈希值连同操作相关信息打包。
- 实现方式:使用 Python 或智能合约语言进行数据的封装,如将关键信息转化为 JSON 或 Solidity 中的结构体。
调用智能合约
系统通过 Web3 接口调用智能合约的特定方法,将打包好的信息发送到以太坊区块链中。此时,智能合约会将数据记录到链上,并生成一个交易哈希(transaction hash)来唯一标识这次上链操作。- 业务动作:系统调用智能合约,将医疗档案哈希及元数据存储到区块链上。
- 实现方式:使用 Web3.py 或者其他区块链开发库,通过智能合约函数(如
addMedicalRecord
)将信息发送到区块链。
确认上链状态
系统需要监控以太坊网络中的交易状态,确保上链成功。在交易确认后,系统会将交易哈希和链上区块编号等信息记录在本地数据库中,以便于未来查询和追溯。- 业务动作:监听区块链事件,确认交易是否已成功写入区块。
- 实现方式:使用 Web3.py 提供的
eventFilter
函数或监听特定交易的状态。
本地数据同步与记录
在交易成功确认后,系统会将链上的交易信息同步到本地数据库。这样可以确保链上和链下数据的一致性,同时提供给用户查询和校验的入口。- 业务动作:在数据库中存储链上交易信息,包括交易哈希、时间戳等。
- 实现方式:更新 MySQL 或其他数据库中的相关表结构,将交易信息和链上信息同步记录。
医疗数据上链的实现原理
智能合约的设计
在以太坊上,需要设计和部署一个专门的智能合约,用于处理医疗档案的上链逻辑。这个智能合约通常包括以下功能:- 记录医疗档案信息:智能合约会有一个函数来接收医疗档案的哈希值、上传者 ID、时间戳等信息,并将这些信息存储在合约的存储中。
- 事件触发:每当有新的医疗档案记录上链时,合约会触发一个事件(Event),方便客户端监听到相关的操作。
Web3 接口的调用
在 Python 端,可以使用 Web3.py 库来与以太坊进行交互。主要步骤包括:- 连接到以太坊节点(使用 Geth 部署的私有链节点)。
- 加载智能合约的 ABI(应用程序二进制接口)和合约地址。
- 调用
addMedicalRecord
函数,并传入医疗档案的哈希值。
交易状态的确认和本地同步
在完成上链操作后,可以监听以太坊的事件,确保上链交易成功。将链上的交易信息同步回本地数据库中,以供后续查询和追溯。
Reactor 设计模式
在医疗云项目中,使用 Reactor 设计模式 来优化元数据服务的请求接收,主要是为了提高系统的 并发处理能力 和 资源利用率。下面我将详细介绍这部分技术的实现细节。
组成
- Reactor:Reactor 在一个单独的线程中运行,负责监听和分发事件,分发给适当的处理程序来对 IO 事件做出反应。它就像公司的电话接线员,它接听来自客户的电话并将线路转移到适当的联系人;
- Handlers:处理程序执行 I/O 事件要完成的实际事件,类似于客户想要与之交谈的公司中的实际官员。Reactor 通过调度适当的处理程序来响应 I/O 事件,处理程序执行非阻塞操作。
背景问题
在元数据服务中,系统需要高效地处理来自多个客户端的并发请求。传统的同步阻塞模型在面对高并发请求时,可能会因为线程阻塞或资源消耗过多而导致性能瓶颈。为了解决这个问题,我们引入了 Reactor 设计模式,采用 事件驱动和异步非阻塞 I/O 的架构来处理元数据服务的请求接收和响应。
技术实现
Reactor 模式 的核心思想是将 事件的监听 和 事件的处理 分离,通过一个 单线程或有限线程的事件循环 来处理大量的 I/O 操作,从而提高系统的并发处理能力。在 Python 中,我们可以使用内置的 selectors
模块和 socket
库来实现 Reactor 模式。
核心架构
Reactor 模式的实现通常包括以下几个核心组件:
- 事件多路复用器(Reactor):负责监听所有的 I/O 事件,并在事件到达时将事件分派给相应的事件处理器。
- 事件处理器(Handler):每个 Handler 负责处理特定类型的事件(如读、写、连接等),并根据业务逻辑做出相应的处理。
具体实现步骤
使用
selectors
模块实现事件监听
Python 提供的selectors
模块支持事件的多路复用,可以通过selectors.DefaultSelector()
实现事件的注册和监听。事件循环与事件处理
事件循环不断轮询已注册的事件,并在事件触发时调用相应的回调函数进行处理。我们可以定义一个事件处理器(Handler)来处理不同类型的 I/O 事件。非阻塞 I/O
在事件处理的过程中,我们使用非阻塞的socket
操作来避免阻塞主线程,确保系统能够高效地响应新请求。
优化点
异步 I/O
通过非阻塞模式和selectors
模块,系统可以高效地处理大量的并发连接,而不会因为 I/O 操作而阻塞。灵活的事件分派
Reactor 模式可以灵活地为不同的事件设置不同的处理器,使得代码结构清晰、维护简单。高效的资源利用
传统的多线程模型中,每个连接通常由一个线程处理,线程的上下文切换和资源占用较高。而使用 Reactor 模式,可以使用单线程来处理所有 I/O 事件,极大地提高了资源的利用效率。
实际项目中的应用
在医疗云项目中,我使用类似的设计模式来优化元数据服务的请求接收。通过 Reactor 设计模式,我们能够 提升高并发处理能力,有效降低线程阻塞带来的性能瓶颈。在实际应用中,处理的元数据请求包括档案的上传、元数据的查询等操作。
Redis 和 Reactor 设计模式
为什么 Redis 选择单线程?
Redis 选择单线程来处理 I/O 和命令执行,主要基于以下几个原因:
避免多线程的复杂性
多线程编程可能带来 线程同步问题 和 锁竞争问题,这些会显著影响 Redis 的性能。Redis 通过单线程来避免这些问题,简化了编程模型,提高了系统的稳定性和一致性。
高效的 I/O 多路复用
Redis 主要面向 I/O 密集型操作,它使用 I/O 多路复用机制(如 epoll)来管理大量客户端的连接,并且所有 I/O 操作都是非阻塞的。在高并发场景下,epoll 的性能远高于传统的 select 和 poll,可以高效地处理数以万计的客户端连接。
数据操作在内存中完成
Redis 的所有数据操作都在内存中完成,没有涉及复杂的磁盘 I/O 操作,因此单线程足以处理大量的命令请求。Redis 对内存的读写速度非常快,完全能够满足大部分应用的需求。
避免上下文切换的开销
多线程程序需要频繁地进行线程上下文切换,而单线程架构则避免了这种开销。对于 Redis 这种高效处理 I/O 的数据库来说,避免不必要的上下文切换可以显著提高性能。
Redis 与 Reactor 模式的相似点
事件驱动:Redis 使用事件驱动的架构,通过 I/O 多路复用监听客户端连接的 I/O 事件,这与 Reactor 模式的核心思想一致。
事件循环:Redis 内部有一个事件循环,用于不断监听 I/O 事件并处理事件。事件循环是 Reactor 模式的关键组件。
非阻塞 I/O:Redis 的 I/O 操作是非阻塞的,这使得它可以高效地处理大量并发连接而不阻塞主线程。
Reactor 业务流程
- Reactor 对象通过 Select 监控客户端请求事件,收到事件后通过 Dispatch 进行分发;
- 如果是建立连接请求事件,则由 Acceptor 通过 Accept 处理连接请求,然后创建一个 Handler 对象处理连接完成后的后续业务处理;
- 如果不是建立连接事件,则 Reactor 会分发调用连接对应的 Handler 来响应;
- Handler 会完成 Read→业务处理→Send 的完整业务流程。