广西建设厅招投标中心网站wordpress可以制作什么网站
news/
2025/9/24 7:12:42/
文章来源:
广西建设厅招投标中心网站,wordpress可以制作什么网站,网络系统管理员在哪里,科讯cms制作网站完整教程大家好#xff0c;我是奇兵。
文章比较长#xff0c;请耐心看完#xff01;
项目上线是每位学编程同学必须掌握的基本技能。之前我已经给大家分享过很多种上线单体项目的方法了#xff0c;今天再出一期微服务项目的部署教程#xff0c;用一种最简单的方法#xff0c;带…大家好我是奇兵。
文章比较长请耐心看完
项目上线是每位学编程同学必须掌握的基本技能。之前我已经给大家分享过很多种上线单体项目的方法了今天再出一期微服务项目的部署教程用一种最简单的方法带大家轻松部署微服务项目。
开始之前先做个小调研啊大家更喜欢看 “真实踩坑版” 的教程还是 “压缩纯净版” 的教程呢
本期教程我还是保持自己一贯的风格依然是保姆级教程包含了一些踩坑过程和解决方案大家跟着做就完事儿~
传统部署
对于这样一个项目如果我们还用传统单机项目的部署方式一个个打 jar 包、用 Java 命令来启动会有哪些问题呢 要一个个安装依赖比如 MySQL 数据库、Redis、消息队列、Nacos非常麻烦 要一个个打 jar 包、一个个手动运行 jar 包非常麻烦 不方便集中观察所有服务的运行状态和资源占用情况
所以为了解决这些问题我们会选用一种更高效的微服务部署方式 —— Docker Compose。
Docker Compose 介绍
在介绍 Docker Compose 前先简单介绍下 Docker。
Docker 是一种容器技术允许开发者将应用程序和所有依赖项如代码、库、配置等制作为 镜像。可以把镜像简单理解为软件安装包可以在不同的计算机上通过它快速安装和启动应用程序容器这些程序独立隔离地运行不受外部环境的影响。 如果要部署微服务项目可能要启动多个 Docker 容器比如 MySQL 容器、用户服务容器等。这时就需要 Docker Compose 了。它是一个容器编排助手用于集中管理多个 Docker 容器的启动和协同工作。可以在一个配置文件中集中定义所有容器以及它们的关系。然后可以使用一行命令启动所有容器而不需要手动运行多个命令。 需要注意的是Docker Compose 通常适用于把所有微服务部署在同一台服务器的场景在真实的企业级项目中往往会使用 K8S 等更专业的容器编排和自动化部署工具更方便地在多个服务器上部署容器。
部署流程
了解了 Docker 和 Docker Compose 的作用后我们来快速了解下部署流程分为 2 大阶段 —— 本地部署和服务器部署。
一、本地部署 梳理服务部署表格 Maven 子父模块打包 Dockerfile 编写 编写环境依赖配置 编写服务配置 调整程序配置 测试访问
二、服务端部署 准备服务器 Docker Compose 安装 同步文件 获取 jar 包 服务启动 测试访问
一、本地部署
第一阶段是本地部署也可以叫做部署准备。
强烈建议大家比起直接操作线上服务器最好是先在本地把所有的流程跑通风险更低、效率更高。
这里我使用的是 Mac 操作系统已经安装了 Docker Desktop 软件管理 Docker 容器会更方便一些。 对于本地没有 Docker 环境的同学这一阶段仔细看一遍有个印象就足够了。可以直接拿我调试好的配置文件在服务器上部署而不用自己调试。 1.1、梳理服务部署表格
在部署微服务项目前首先要规划好要部署哪些服务、以及各服务的关键信息比如服务名称、版本号、占用端口号、关键配置等。
对于我的在线判题项目梳理好的服务表格如下
服务名称英文名端口号版本号服务类别数据库mysql3306v8环境依赖缓存redis6379v6环境依赖消息队列rabbitmq5672, 15672v3.12.6环境依赖注册中心nacos8848v2.2.0环境依赖网关服务gateway8101java 8业务服务用户服务yuoj-backend-user-service8102java 8业务服务题目服务yuoj-backend-question-service8103java 8业务服务判题服务yuoj-backend-judge-service8104java 8业务服务
为什么这里我要划分服务类别为 “环境依赖” 和 “业务服务” 呢
因为在启动服务时必须要先启动环境依赖才能启动业务服务否则就会报类似 “无法连接数据库” 之类的错误。
1.2、Maven 子父模块打包
对于微服务项目我们通常是使用 Maven 的子父模块功能进行管理的。需要部署项目时不用针对每个子服务单独执行 mvn package 命令进行打包而是可以一键打包所有服务。
想要实现这个功能需要给子父模块的依赖文件pom.xml进行一些配置主要包括
1父模块配置
在父模块的 pom.xml 文件中引入 spring-boot-maven-plugin 即可注意一定不要配置 configuration 和 repackage
示例代码如下
plugingroupIdorg.springframework.boot/groupIdartifactIdspring-boot-maven-plugin/artifactIdversion${spring-boot.version}/version
/plugin2子模块配置
修改所有需要启动 Spring Boot 的服务用户服务、题目服务、判题服务、网关服务的子模块 pom.xml 文件。
主要是增加 executions 配置使用 spring-boot-maven-plugin 的 repackage 命令来构建子模块从而自动在构建时将公共模块的依赖打入 jar 包。
示例代码如下
plugingroupIdorg.springframework.boot/groupIdartifactIdspring-boot-maven-plugin/artifactIdexecutionsexecutionidrepackage/idgoalsgoalrepackage/goal/goals/execution/executions
/plugin1.3、Dockerfile 编写
Dockerfile 是定义 Docker 容器镜像构建过程的文件包括容器镜像使用的基础环境、容器内的依赖和文件、容器的配置、启动命令等。
有了 Dockerfile我们就能很轻松地制作出自己的容器镜像。
虽然 Dockerfile 的写法并不复杂但我还是建议大家尽量不要自己写直接去网上找个差不多的项目复制粘贴别人的 Dockerfile 就足够了
给大家提供 2 种常用的 Spring Boot 项目的 Dockerfile。
1复制 jar 包版
思路在本地打好 jar 包后复制 jar 包到容器中运行
示例代码如下
# 基础镜像
FROM openjdk:8-jdk-alpine# 指定工作目录
WORKDIR /app# 将 jar 包添加到工作目录比如 target/yuoj-backend-user-service-0.0.1-SNAPSHOT.jar
ADD {本地 jar 包路径} . # 暴露端口
EXPOSE {服务端口号}# 启动命令
ENTRYPOINT [java,-jar,/app/{jar 包名称},--spring.profiles.activeprod]2Maven 打包版
思路复制本地代码到容器中在容器中使用 Maven 打包再运行
示例代码如下
# 基础镜像
FROM maven:3.8.1-jdk-8-slim as builder# 指定工作目录
WORKDIR /app# 添加源码文件
COPY pom.xml .
COPY src ./src# 构建 jar 包跳过测试
RUN mvn package -DskipTests# 启动命令
ENTRYPOINT [java,-jar,/app/target/{jar 包名称},--spring.profiles.activeprod]此处由于我们的微服务项目可以一键打好所有子服务的 jar 包就没必要每个服务单独在容器中打包了所以选择第一种方式的 Dockerfile。
我们需要给每个 Spring Boot 服务用户服务、题目服务、判题服务、网关服务都编写一个 Dockerfile放到每个子服务的根目录下。 以用户服务为例示例代码如下
# 基础镜像
FROM openjdk:8-jdk-alpine# 指定工作目录
WORKDIR /app# 将 jar 包添加到工作目录比如 target/yuoj-backend-user-service-0.0.1-SNAPSHOT.jar
ADD target/yuoj-backend-user-service-0.0.1-SNAPSHOT.jar .# 暴露端口
EXPOSE 8102# 启动命令
ENTRYPOINT [java,-jar,/app/yuoj-backend-user-service-0.0.1-SNAPSHOT.jar,--spring.profiles.activeprod]建议先在本地利用 IDEA 开发工具调通镜像构建流程确保每个 Dockerfile 都是可以成功制作镜像的 查看容器的启动日志发现能够启动服务、看到 Spring 图标即可 1.4、编写环境依赖配置
接下来我们就要编写 Docker Compose 的配置文件了可以根据配置文件快速启动多个服务。
之前我们已经梳理了服务部署表格将服务划分为了 “环境依赖” 和 “业务服务”。
由于业务服务依赖 MySQL 等环境依赖所以需要拆分 2 套 Docker Compose 的配置文件分别为 docker-compose.env.yml 环境配置和 docker-compose.service.yml 业务服务配置保证先成功启动依赖再启动服务。
学过 Docker Compose 的同学可能听说过 depends_on 配置也能决定服务的启动顺序。但是千万注意depends_on 并不会等待服务完全就绪只是确保它们在启动时的顺序并不稳定。
如何编写 Docker Compose 文件呢
和 Dockerfile 一样直接去网上找现成的 Docker Compose file复制粘贴过来略做修改就能使用了~
再配合以下 2 个网站完全无需记忆 Docker Compose 的写法 Docker Compose file 官方文档https://docs.docker.com/compose/compose-file/ 搜索现成的 Docker 镜像https://hub.docker.com/
当然现在 AI 时代了还有更简单的方式
直接把我们整理好的服务部署需要喂给 GPT让 AI 帮我们生成配置即可~
示例 prompt
现在我需要用 docker compose 来部署 mysql 83306 端口usernameroot,password123456
redis 6无密码6379端口、rabbitmq v.3.12.6 5672 端口 password: guestusername: guest、nacos 2.2.08848端口还有 4 个本地的 springboot 服务名称分别为yuoj-backend-user-service 8102端口、yuoj-backend-question-service 8103端口、yuoj-backend-judge-service 8104端口、yuoj-backend-gateway 8101 端口每个服务本地目录都有一个 Dockerfile请帮我自动生成 docker compose 的 yml 配置文件要求这些服务网络能够连通效果还是非常不错的只要你描述地足够清楚生成的配置完全可用 由于这篇文章是教程嘛我就带大家通过调试的方式一步步完成 Docker Compose 文件最后会把完整的 Docker Compose 文件给大家分享出来大家直接用就行了~
我们要分别在 Docker Compose 中定义 4 大基础依赖包括 MySQL、Redis、RabbitMQ 和 Nacos。
1MySQL
我们不仅要创建一个 MySQL 服务还要在创建服务后自动创建我们需要的库表结构。
所以需要先准备数据库 SQL 脚本文件里面包含了建库、建表语句我们把它放在微服务项目根目录的 mysql-init 文件夹中 由于要在本地启动 MySQL还需要定义一个文件夹 .mysql-data 来存放 MySQL 的持久化数据防止容器重启后数据丢失。
做好这两点后就可以编写 docker-compose.env.yml 文件了先只写一个 MySQL 服务示例代码如下
关键配置的含义我都写到注释里了
version: 3
services:mysql:image: mysql:8 # 使用的镜像container_name: yuoj-mysql # 启动的实例名称environment:MYSQL_ROOT_PASSWORD: 123456 # root 用户密码ports:- 3306:3306 # 端口映射volumes:- ./.mysql-data:/var/lib/mysql # 将数据目录挂载到本地目录以进行持久化- ./mysql-init:/docker-entrypoint-initdb.d # 自动执行启动脚本restart: always # 崩溃后自动重启networks:- mynetwork # 指定网络
networks:mynetwork: # 自定义网络实现网络互通和隔离写好配置文件后可以直接在 IDEA 里执行 Docker Compose 文件调试 MySQL 的运行 运行成功后我们可以在本地成功连接数据库 2Redis
Redis 服务的定义和启动操作和 MySQL 服务几乎一致Redis 的 Docker Compose 配置示例代码如下
version: 3
services:redis:image: redis:6container_name: yuoj-redisports:- 6379:6379networks:- mynetworkvolumes:- ./.redis-data:/data # 持久化
networks:mynetwork:然后在本地执行 Docker Compose 文件启动 Redis 服务并且尝试进入 Terminal 来调试 Redis 3RabbitMQ 同 MySQL 和 RedisRabbitMQ 的 Docker Compose 配置示例代码如下
version: 3
services:rabbitmq:image: rabbitmq:3.12.6-management # 支持管理面板的消息队列container_name: yuoj-rabbitmqenvironment:RABBITMQ_DEFAULT_USER: guestRABBITMQ_DEFAULT_PASS: guestports:- 5672:5672- 15672:15672 # RabbitMQ Dashboard 端口volumes:- ./.rabbitmq-data:/var/lib/rabbitmq # 持久化networks:- mynetwork
networks:mynetwork:本地执行 Docker Compose 文件启动 RabbitMQ 服务然后可以访问 localhost:15672 查看到管理面板就表示启动成功了~
账号密码都是 guest 4Nacos
和其他服务一样Nacos 也需要编写 Docker Compose 配置。
但是在选择 Nacos 镜像时必须要注意建议选择支持 linux/arm64 架构的镜像版本比如 v2.2.0-slim否则后面可能会无法运行 Nacos 示例配置文件如下
version: 3
services:nacos:image: nacos/nacos-server:v2.2.0-slimcontainer_name: yuoj-nacosports:- 8848:8848volumes:- ./.nacos-data:/home/nacos/datanetworks:- mynetworkenvironment:- MODEstandalone # 单节点模式启动- PREFER_HOST_MODEhostname # 支持 hostname- TZAsia/Shanghai # 控制时区
networks:mynetwork:然后在本地执行 Docker Compose 启动 Nacos访问 localhost:8848/nacos 能够看到管理页面就表示运行成功了~
管理页面的账号和密码默认都是 nacos 完整 Docker Compose 文件
分别调试完上述服务后我们把所有的配置拼在一起就得到了完整的文件文件名为 docker-compose.env.yml。
完整代码如下
version: 3
services:mysql:image: mysql:8 # 使用的镜像container_name: yuoj-mysql # 启动的实例名称environment:MYSQL_ROOT_PASSWORD: 123456 # root 用户密码ports:- 3306:3306 # 端口映射volumes:- ./.mysql-data:/var/lib/mysql # 将数据目录挂载到本地目录以进行持久化- ./mysql-init:/docker-entrypoint-initdb.d # 启动脚本restart: always # 崩溃后自动重启networks:- mynetwork # 指定网络redis:image: redis:6container_name: yuoj-redisports:- 6379:6379networks:- mynetworkvolumes:- ./.redis-data:/data # 持久化rabbitmq:image: rabbitmq:3.12.6-management # 支持管理面板的消息队列container_name: yuoj-rabbitmqenvironment:RABBITMQ_DEFAULT_USER: guestRABBITMQ_DEFAULT_PASS: guestports:- 5672:5672- 15672:15672 # RabbitMQ Dashboard 端口volumes:- ./.rabbitmq-data:/var/lib/rabbitmq # 持久化networks:- mynetworknacos:image: nacos/nacos-server:v2.2.0-slimcontainer_name: yuoj-nacosports:- 8848:8848volumes:- ./.nacos-data:/home/nacos/datanetworks:- mynetworkenvironment:- MODEstandalone # 单节点模式启动- PREFER_HOST_MODEhostname # 支持 hostname- TZAsia/Shanghai # 控制时区
networks:mynetwork:1.5、编写业务服务配置
用同样的方式我们可以编写业务服务的 Docker Compose 文件文件名称 docker-compose.service.yml。
示例代码如下其中需要格外关注的配置是 build 和 depends_on
version: 3
services:yuoj-backend-gateway:container_name: yuoj-backend-gatewaybuild: # 服务的 Docker 构建文件位置context: ./yuoj-backend-gatewaydockerfile: Dockerfileports:- 8101:8101networks:- mynetworkyuoj-backend-user-service:container_name: yuoj-backend-user-servicebuild:context: ./yuoj-backend-user-servicedockerfile: Dockerfileports:- 8102:8102networks:- mynetworkdepends_on: # 本服务依赖的服务控制启动先后顺序- yuoj-backend-gatewayyuoj-backend-question-service:container_name: yuoj-backend-question-servicebuild:context: ./yuoj-backend-question-servicedockerfile: Dockerfileports:- 8103:8103networks:- mynetworkdepends_on:- yuoj-backend-user-service- yuoj-backend-gatewayyuoj-backend-judge-service:container_name: yuoj-backend-judge-servicebuild:context: ./yuoj-backend-judge-servicedockerfile: Dockerfileports:- 8104:8104networks:- mynetworkdepends_on:- yuoj-backend-user-service- yuoj-backend-question-service- yuoj-backend-gateway# 网络不定义的话就是默认网络
networks:mynetwork:1.6、调整程序配置
编写好上述配置文件后本地尝试运行 Docker Compose 业务服务结果发现报错啦依赖服务的地址访问不通
这是由于之前我们的项目访问依赖服务时全部是使用了固定的 IP 地址比如 localhost而容器内部的 localhost或 127.0.0.1通常指向容器本身而不是宿主主机。所以为了在容器内访问其他服务程序中应该使用服务名称而不是 localhost。
我们给每个 Spring Boot 服务都增加一套 prod 上线配置在配置中更改服务调用地址。
用户服务、题目服务和判题服务的 application-prod.yml 配置修改如下
# 生产环境配置文件
spring:# 数据库配置datasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://mysql:3306/yuoj # localhost 改为 mysqlusername: rootpassword: 123456# Redis 配置redis:database: 1host: redis # localhost 改为 redisport: 6379timeout: 5000cloud:nacos:discovery:server-addr: nacos:8848 # localhost 改为 nacosrabbitmq:host: rabbitmq # localhost 改为 rabbitmqport: 5672password: guestusername: guestGateway 网关服务的配置修改如下
spring:cloud:nacos:discovery:server-addr: nacos:8848 # localhost 改为 nacosgateway:routes:- id: yuoj-backend-user-serviceuri: lb://yuoj-backend-user-servicepredicates:- Path/api/user/**- id: yuoj-backend-question-serviceuri: lb://yuoj-backend-question-servicepredicates:- Path/api/question/**- id: yuoj-backend-judge-serviceuri: lb://yuoj-backend-judge-servicepredicates:- Path/api/judge/**application:name: yuoj-backend-gatewaymain:web-application-type: reactive
server:port: 8101
knife4j:gateway:enabled: truestrategy: discoverdiscover:enabled: trueversion: swagger2然后执行 mvn package 命令重新打包、执行 Docker Compose。
结果发现大多数服务都启动了但是判题服务还有报错。 这是因为程序在创建消息队列时存在硬编码的变量指定了 host 为 localhost示例代码如下
ConnectionFactory factory new ConnectionFactory();
factory.setHost(localhost);
Connection connection factory.newConnection();
Channel channel connection.createChannel();
String EXCHANGE_NAME code_exchange;
channel.exchangeDeclare(EXCHANGE_NAME, direct);举这个例子是为了告诉大家在程序中尽量不要写固定 IP 或域名全部改为动态读取配置文件便于修改。
示例修改后的代码如下
/*** 用于创建测试程序用到的交换机和队列只用在程序启动前执行一次*/
Slf4j
Component
public class InitRabbitMqBean {Value(${spring.rabbitmq.host:localhost})private String host;PostConstructpublic void init() {try {ConnectionFactory factory new ConnectionFactory();factory.setHost(host);Connection connection factory.newConnection();Channel channel connection.createChannel();String EXCHANGE_NAME code_exchange;channel.exchangeDeclare(EXCHANGE_NAME, direct);// 创建队列随机分配一个队列名称String queueName code_queue;channel.queueDeclare(queueName, true, false, false, null);channel.queueBind(queueName, EXCHANGE_NAME, my_routingKey);log.info(消息队列启动成功);} catch (Exception e) {log.error(消息队列启动失败);}}
}1.7、测试访问
修复上述问题后所有服务都可以通过 Docker Compose 文件启动了。
然后我们访问 localhost:8101/doc.html 网关地址能够看到 Swagger 聚合接口文档。 依次调用用户注册 登录 获取登录用户信息 创建题目接口全部执行成功。
至此第一阶段就完成啦。
二、服务器部署
在第二阶段我们的目标就是在真实的 Linux 服务器上部署微服务项目。有了第一阶段的准备第二阶段简直可以说是易如反掌
2.1、准备服务器
首先我们要有一台 Linux 服务器。
选择服务器前我们必须要评估下微服务项目的内存占用千万别把服务器的内存买小了
可以使用 Docker Desktop 直接查看内存占用虚拟机内存大概占用了 8 个 G、容器实际内存占用了 4 个 G 那我们搞多少内存的服务器呢
我猜很多同学会说 8 G奈何我天生反骨明知山有虎偏向虎山行主要是想省 我就搞一台 2 核 4 G 的服务器吧发行版是 CentOS 7.9 Linux咱们来猜一猜它够不够部署这套有 4 个业务服务的微服务项目呢
咱们一起来见证下
2.2、Docker Compose 安装
有了服务器后直接参考 Docker Compose 官方文档来安装。这里我们使用 Docker Compose V2 版本相比 V1 版本统一了命令使用更方便
Docker Compose V2 地址https://docs.docker.com/compose/migrate/
Docker Compose Linux 安装https://docs.docker.com/compose/install/linux/#install-using-the-repository 安装过程很简单跟着官方文档来就行了主要包括以下几个步骤
1设定安装来源
sudo yum install -y yum-utils
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo2安装 Docker 和 Docker Compose
sudo yum install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin3启动 Docker
sudo systemctl start docker4测试 Docker
systemctl status docker
sudo docker run hello-world2.3、同步文件
接下来我们需要把本地折腾好的微服务项目源码上传到服务器上可以选择用 FTP 或 SSH 连接文件手动上传文件。
我这里使用 JetBrains 开发工具的远程部署功能可以配置文件自动上传步骤如下
1进入远程部署配置 2添加远程部署配置
这里建议大家不要暴露自己的服务器 IP 啊当你看到本文的时候其实我已经把服务器的 IP 更换掉了哈哈哈哈哈哈哈哈 3指定连接的服务器配置 4配置本地文件和服务器文件路径映射 5开启自动上传 6首次需要手动上传文件。
上传前记得先删除无用的文件然后右键项目根目录点击部署上传代码 上传成功在服务器对应路径/code/yuoj-backend-microservice下能看到已上传的文件列表 2.4、获取 jar 包
光把代码上传到服务器还是不够的因为我们构建 Docker 镜像需要 jar 包。
有 2 种方式得到 jar 包 本地执行 mvn package 打好 jar 包然后再上传 服务器上装 Maven在服务器上打包
但是因为 jar 包比较大频繁改动的话同步速度会比较慢所以更建议第二种方式步骤如下
1安装 Maven
sudo yum install maven2安装好后执行打包
sudo mvn package打包成功 2.5、服务启动
所有一切准备就绪接下来就是使用 Docker Compose 命令分别启动环境依赖和业务服务啦。
1启动环境依赖
先使用 docker compose 一行命令启动环境依赖
docker compose -f docker-compose.env.yml up注意 老版本使用 docker-compose 替代 docker compose 如果没有权限命令前加上 sudo
然后喝杯咖啡等待启动即可~
启动成功后我们可以通过公网 IP 来尝试访问服务。
先进入到云服务商的服务器配置页修改服务器的防火墙配置放通以下端口 然后像访问本地服务一样分别去访问 MySQL、Redis、RabbitMQ、Nacos 即可应该都是成功的。 由于进程在前台启动会影响我们的操作所以先按 ctrl c 退出加上 -d 参数让容器在后台启动
sudo docker compose -f docker-compose.env.yml up -d试着查看下 docker 容器的状态
sudo docker stats能够查看到所有容器的资源占用情况 实话说我开始紧张了不知道 4 G 的内存够不够撑。。。
2启动业务服务
确保环境依赖都启动成功后接下来启动业务服务
docker compose -f docker-compose.service.yml up项目全部启动看得很爽 正常来说应该会启动成功但如果运气背可能会有失败比如我这的网关服务就启动失败了。
如果某个服务启动失败可以再次单独只启动它比如网关服务
sudo docker compose -f docker-compose.service.yml up yuoj-backend-gateway2.6、测试访问
最后像验证本地微服务项目部署一样访问线上网关的接口文档 http://你的服务器 IP:8101/doc.html 依次调用用户注册 登录 获取登录用户信息 创建题目全部成功~ 最后使用 docker stats 命令查看 Docker 容器的状态发现总共的内存占用大概 3 G也就是说 4 G 内存的服务器是完全足够小型微服务项目的部署了~ 至此微服务项目部署教程就结束了。 喜欢的话点点赞收藏一下谢谢
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/915169.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!