ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Hyperf 微服务信创全栈部署(麒麟 + 达梦端到端)

Hyperf 微服务信创全栈部署(麒麟 + 达梦端到端) 第 4 章 Hyperf 微服务信创全栈部署麒麟 达梦端到端4.1 为什么选 Hyperf而不是 Laravel/ThinkPHP大白话信创项目的三个特点决定了框架选型要求高并发政务大厅、金融交易系统单机要扛住 5 万 QPS要求微服务化模块间解耦方便不同供应商分包需要服务注册发现、熔断降级要求全国产适配数据库、缓存、消息队列都是国产框架的数据库抽象层要能快速对接。Hyperf 满足这三点基于 Swoole 协程高并发、内置服务治理微服务、DB 层支持自定义驱动适配达梦。4.2 准备工作装 Composer 和创建项目# 1. 装 Composer国内用阿里云镜像cd/usr/local/srcwgethttps://mirrors.aliyun.com/composer/composer.pharsudomvcomposer.phar /usr/local/bin/composersudochmodx /usr/local/bin/composercomposerconfig-grepo.packagistcomposerhttps://mirrors.aliyun.com/composer/# 2. 创建 Hyperf 项目cd/var/wwwcomposercreate-project hyperf/hyperf-skeleton hyperf-democdhyperf-demo# 3. 检查依赖Swoole 必须 5.0/usr/local/php8/bin/php--riswoole|grepVersion# 若低于 5.0回到第 3 章升级# 4. 初次启动测试/usr/local/php8/bin/php bin/hyperf.php start# 期望输出Hyperf HTTP Server started at http://0.0.0.0:9501# 访问curl http://127.0.0.1:9501 应返回 Hello Hyperf4.3 对接达梦数据库最大的坑在这4.3.1 达梦和 MySQL 的差异速查表差异点MySQL 5.7/8.0达梦 DM8Hyperf 代码改动表名大小写不敏感Linux 上可配默认敏感建表全用大写或全小写自增主键AUTO_INCREMENTIDENTITY(1,1)迁移文件要改分页LIMIT 10 OFFSET 20LIMIT 20, 10查询构造器要判断驱动字符串拼接CONCAT()日期函数NOW()SYSDATEORM 层统一JSON 类型原生支持8.1.2 才有老版本用TEXT事务隔离级别RR可重复读RC读已提交显式设置4.3.2 安装达梦 PDO 驱动最折腾的一步达梦官方提供的是PDO_ODBC驱动不是直接的 PDO_DM。步骤如下# 1. 先装 unixODBC麒麟 V10sudoyuminstall-yunixODBC unixODBC-devel# 统信 UOS 用# sudo apt install -y unixodbc unixodbc-dev# 2. 下载达梦客户端需要去达梦官网注册账号下载 DM8 客户端# 假设下载到 /tmp/dm8_client_linux_x86_64.tar.gz海光# ARM64 的下载文件名是 dm8_client_linux_aarch64.tar.gzcd/usr/local/srctar-zxf/tmp/dm8_client_linux_*.tar.gzsudomvdm8_client /usr/local/dm8# 3. 配置 ODBC 数据源sudotee/etc/odbc.ini/dev/nullEOF [DM8] Driver /usr/local/dm8/drivers/libdodbc.so Description DaMeng ODBC Driver SERVER 192.168.1.100 # 达梦服务器 IP PORT 5236 DATABASE SYSDBA # 默认数据库 UID SYSDBA PWD SYSDBA EOF# 4. 测试 ODBC 连接isql-vDM8# 若能进入 SQL 提示符输入 SELECT * FROM V$VERSION; 能返回版本号说明通了# 5. 确认 PHP 已编译 PDO_ODBC第 1 章编译时如果没加 --with-pdo-odbc要重编/usr/local/php8/bin/php-m|grep-ipdo_odbc# 若没有回到源码目录重新 configure# ./configure --with-pdo-odbcunixODBC,/usr ... 其他参数同第 1 章4.3.3 Hyperf 配置达梦连接编辑config/autoload/databases.php?phpreturn[defaultenv(DB_DRIVER,dm8),// 改为 dm8connections[dm8[driverpdo,// 注意不是 dm达梦走 PDO_ODBCdsnodbc:DM8,// 对应 /etc/odbc.ini 里的 [DM8]usernameenv(DB_USERNAME,SYSDBA),passwordenv(DB_PASSWORD,SYSDBA),charsetutf8,collation,prefix,options[// 达梦的事务隔离级别默认是 RC业务需要 RR 的话要显式设置\PDO::ATTR_ERRMODE\PDO::ERRMODE_EXCEPTION,\PDO::ATTR_CASE\PDO::CASE_NATURAL,// 保持原始大小写\PDO::ATTR_ORACLE_NULLS\PDO::NULL_NATURAL,],pool[min_connections1,max_connections20,connect_timeout10.0,wait_timeout3.0,heartbeat60,// 达梦默认空闲超时 10 分钟这里 60 秒心跳保活max_idle_time60.0,],],// 保留 MySQL 配置方便本地开发切换mysql[drivermysql,hostenv(DB_HOST,127.0.0.1),portenv(DB_PORT,3306),databaseenv(DB_DATABASE,hyperf),usernameenv(DB_USERNAME,root),passwordenv(DB_PASSWORD,),charsetutf8mb4,collationutf8mb4_unicode_ci,prefix,pool[min_connections1,max_connections10,connect_timeout10.0,wait_timeout3.0,heartbeat60,max_idle_time60.0,],],],];4.3.4 迁移文件适配达梦Hyperf 用的是类似 Laravel 的 migration但语法要改?php// database/migrations/2024_01_01_000000_create_users_table.phpuseHyperf\Database\Schema\Schema;useHyperf\Database\Schema\Blueprint;useHyperf\Database\Migrations\Migration;classCreateUsersTableextendsMigration{publicfunctionup():void{// 获取当前连接驱动$driverconfig(databases.default);Schema::create(users,function(Blueprint$table)use($driver){if($driverdm8){// 达梦的自增语法$table-bigInteger(ID)-comment(用户ID);// 注意大写$table-string(USERNAME,50)-unique()-comment(用户名);$table-string(PASSWORD,255)-comment(密码);$table-timestamp(CREATED_AT)-useCurrent()-comment(创建时间);$table-timestamp(UPDATED_AT)-useCurrent()-comment(更新时间);$table-primary(ID);// 手动加自增达梦不支持 $table-id()DB::statement(ALTER TABLE USERS MODIFY ID IDENTITY(1,1));}else{// MySQL 标准写法$table-id();$table-string(username,50)-unique();$table-string(password);$table-timestamps();}});}publicfunctiondown():void{Schema::dropIfExists(users);}}执行迁移/usr/local/php8/bin/php bin/hyperf.php migrate# 若报错 table or view does not exist: MIGRATIONS说明达梦里还没有迁移表正常继续# 若报错 ORA-00001: unique constraint violated说明表已存在先 migrate:rollback4.3.5 查询构造器的兼容性处理问题Hyperf 的DB::table()-paginate()生成的 SQL 在达梦上语法错误。解决自定义一个DmQueryBuilder?php// app/Kernel/Db/DmQueryBuilder.phpnamespaceApp\Kernel\Db;useHyperf\Database\Query\Builder;classDmQueryBuilderextendsBuilder{/** * 重写分页方法适配达梦的 LIMIT 语法与 MySQL 顺序相反 */publicfunctionforPage($page,$perPage15){$offset($page-1)*$perPage;// 达梦的语法LIMIT offset, limit和 MySQL 反着return$this-offset($offset)-limit($perPage);}}在config/autoload/databases.php里注册dm8[// ...query_builder\App\Kernel\Db\DmQueryBuilder::class,],4.4 Hyperf 微服务组件配置服务注册与发现信创项目常用Consul或Nacos做服务注册中心。这里以 Consul 为例Nacos 是 Java 栈信创环境可能要换国产的如分布式协调服务 TongLINK。4.4.1 安装 Consul在管理节点上# 下载ARM64 用 consul_*_linux_arm64.zipcd/usr/local/srcwgethttps://releases.hashicorp.com/consul/1.17.0/consul_1.17.0_linux_amd64.zipunzipconsul_1.17.0_linux_amd64.zipsudomvconsul /usr/local/bin/# 启动单机 dev 模式生产要搭集群consul agent-dev-bind0.0.0.0-client0.0.0.0# 检查consul members# 期望输出Node Address Status Type4.4.2 Hyperf 配置服务注册安装依赖cd/var/www/hyperf-democomposerrequire hyperf/consul hyperf/service-governance编辑config/autoload/consul.php?phpreturn[urihttp://192.168.1.200:8500,// Consul 服务器地址];编辑config/autoload/services.php配置要注册的服务?phpreturn[enable[discoverytrue,// 启用服务发现registertrue,// 启用服务注册],consumers[],// 消费的外部服务后面配providers[[nameuser-service,// 服务名service\App\JsonRpc\UserServiceInterface::class,// 接口protocoljsonrpc-http,// 协议registry[protocolconsul,// 注册到 Consuladdresshttp://192.168.1.200:8500,],],],drivers[consul[urihttp://192.168.1.200:8500,token,check[deregister_critical_service_after90m,interval10s,// 健康检查间隔],],],];4.4.3 定义 JSON-RPC 服务微服务间通信创建接口?php// app/JsonRpc/UserServiceInterface.phpnamespaceApp\JsonRpc;interfaceUserServiceInterface{publicfunctiongetUserById(int$id):array;publicfunctioncreateUser(array$data):int;}实现服务?php// app/JsonRpc/UserService.phpnamespaceApp\JsonRpc;useHyperf\RpcServer\Annotation\RpcService;#[RpcService(name:user-service,protocol:jsonrpc-http,server:jsonrpc-http)]classUserServiceimplementsUserServiceInterface{publicfunctiongetUserById(int$id):array{// 实际业务从达梦查数据$user\Hyperf\DbConnection\Db::connection(dm8)-table(USERS)-where(ID,$id)-first();return$user?(array)$user:[];}publicfunctioncreateUser(array$data):int{return\Hyperf\DbConnection\Db::connection(dm8)-table(USERS)-insertGetId([USERNAME$data[username],PASSWORDpassword_hash($data[password],PASSWORD_BCRYPT),CREATED_ATdate(Y-m-d H:i:s),UPDATED_ATdate(Y-m-d H:i:s),]);}}启动服务/usr/local/php8/bin/php bin/hyperf.php start# 查看 Consul UIhttp://192.168.1.200:8500/ui/dc1/services# 应能看到 user-service 已注册健康检查为绿色4.4.4 其他服务调用服务发现在另一个 Hyperf 项目里如 order-service配置消费者?php// config/autoload/services.phpreturn[consumers[[nameuser-service,service\App\JsonRpc\UserServiceInterface::class,// 接口要一致protocoljsonrpc-http,load_balancerrandom,// 负载均衡策略registry[protocolconsul,addresshttp://192.168.1.200:8500,],],],];在控制器里调用?phpnamespaceApp\Controller;useApp\JsonRpc\UserServiceInterface;useHyperf\Di\Annotation\Inject;classOrderController{#[Inject]privateUserServiceInterface$userService;publicfunctioncreate(){// 跨服务调用$user$this-userService-getUserById(1);if(empty($user)){return[code404,messageUser not found];}// 创建订单逻辑...return[code0,data[order_id12345]];}}4.5 容器化与部署systemd 方式生产环境不能直接php bin/hyperf.php start前台运行SSH 断了就挂要用 systemd 托管。sudotee/etc/systemd/system/hyperf-user-service.service/dev/nullEOF [Unit] DescriptionHyperf User Service Afternetwork.target consul.service dm8.service [Service] Typesimple Userwww Groupwww WorkingDirectory/var/www/hyperf-demo ExecStart/usr/local/php8/bin/php bin/hyperf.php start ExecReload/bin/kill -USR1 $MAINPID Restarton-failure RestartSec5s LimitNOFILE65535 StandardOutputjournal StandardErrorjournal [Install] WantedBymulti-user.target EOFsudosystemctl daemon-reloadsudosystemctlenablehyperf-user-servicesudosystemctl start hyperf-user-servicesudosystemctl status hyperf-user-service查看日志sudojournalctl-uhyperf-user-service-f
返回列表