从零开始搞个简易分布式部署环境

news2025/6/3 21:29:14

从零开始,意味着连个服务器都没有,所以第一步,随便上哪个顺眼的云厂家去租个便宜大碗的服务器(不要window系统的就行),说大碗也不太对,主要是这碗能在手里用得久,这个就自己扒拉去了。

简易,意味着这个分布式环境都是在这个服务器里用容器搭出来的自娱自乐的环境,跟实际正经的由不同主机组成的分布式环境依然有相当大的区别,最大的区别就是:省钱!

至于为什么不在自己电脑上搞虚拟机双系统啥的去模拟,我只能说我自己的破烂电脑背上这么多负担还真不一定比租个云服务器便宜方便,如果你电脑配置很牛逼,那当我没说。

那么,就开始从零开始了。

这个分布式环境都需要什么?

首先,要有一个应用,如果是搞Java开发的,大概率就会是个springboot应用,那么随便写一个返回 hello world 的 controller 再写好 Application 最后打包成一个 jar,这就是第一个需要的东西。

这一步是在自己本机完成的,也是本文中本机唯一做的事,接下来的其他步骤就全是在租下来的云服务器上的操作了。

云服务器环境准备

首先,更新服务器的 apt 或者 yum 或其他什么都好的安装工具,因为不更新的话有很大概率你啥都安装不了(苦涩)。

sudo apt update && sudo apt upgrade
# 或者
sudo yum update
# 下面各种乱七八糟的安装就用 apt 的写了,yum 的也一样,就这三个字母的差别。

然后,下载 docker-ce ,注意这个后缀,带此后缀的是 docker 的社区版,免费开源,更新频繁(每月发布新版本),适合个人开发者和小团队使用。

apt install -y docker-ce docker-ce-cli containerd.io

在这个环节,大概率会遇到:

  1. yum 版本太低,docker-ce没法下载,忽悠你下载 docker

解: yum install -y yum-utils 把Red Hat Enterprise Linux(RHEL)或 CentOS 的系统上可能缺失(因为系统已经被改成了阿里云的系统)的 yum-utils 下载回来,这是个包管理工具。

  1. 没配置下载仓库

解: yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo 记得用国内镜像,docker 官方镜像容易超时连接失败。

  1. 下载完docker命令不生效

解:systemctl enable docker检查 docker 是否可用,systemctl start docker启动docker。

  1. 其他

解:未完待续……

大部分问题善用搜索引擎或描述给人机师傅基本也能得到解决。这里就只记录我自己遇到过的。

JDK下载与容器创建

在 docker 安装完后,就开始下载 jdk 了。我准备测试三个jdk环境:8、11、17。

# 下载解压jdk8,下面的 11 和 17 也是相同的命令
wget -qO- https://download.java.net/openjdk/jdk8u42/ri/openjdk-8u42-b03-linux-x64-14_jul_2022.tar.gz | tar -xz
wget -qO- https://download.java.net/openjdk/jdk11/ri/openjdk-11+28_linux-x64_bin.tar.gz | tar -xz
wget -qO- https://download.java.net/openjdk/jdk17/ri/openjdk-17+35_linux-x64_bin.tar.gz | tar -xz

这三个jdk需要放在单独的文件夹下,因为等会儿创建容器的时候要把这个路径映射到容器里,方便日后容器内测试不同版本jdk。这里也先提前写一个切换环境变量的脚本放在同级文件夹下,这样容器内就可以直接操作使用。

#!/bin/bash

# 检查是否传入参数(JDK版本号)
if [ $# -eq 0 ]; then
  echo "错误:请指定JDK版本号(如8、11、17等)"
  echo "用法:./set_java.sh <版本号>"
  exit 1
fi

# 设置JAVA_HOME和PATH
export JAVA_HOME="/opt/java/jdk$1"  # 使用第一个参数$1替换版本号
export PATH="$JAVA_HOME/bin:$PATH"

# 验证Java版本
java -version

经测试,容器内使用这个脚本需要用source而不是bash执行才能顺利地修改容器内的 Java 环境,有些教程会让写成系统命令,配置成类似 systemctl 那样的,但我这边用了下不太行得通。而用bash执行会创建一个隔离的shell环境,导致切换环境变量的操作只在这次执行中生效,当执行完毕想再用 java -version 确认版本会发现依然是旧的jdk。

脚本准备好,接下来就是创建容器了。

# 容器创建
docker run -itd --name apps \
        # 这里依次映射了三个版本的jdk路径
        -v /home/workspace/java/jdk8:/opt/java/jdk8 \
        -v /home/workspace/java/jdk11:/opt/java/jdk11 \
        -v /home/workspace/java/jdk17:/opt/java/jdk17 \
        # 也可以直接把上层文件夹映射到容器里
        -v /home/workspace/java:/opt/java \
        # 这里是要部署的应用的映射地址
        -v /home/workspace/app1/app1:/data/app1/ \
        # 预先配置容器创建时的jdk版本
        -e JAVA_HOME=/opt/java/jdk8 \
        -e PATH=/opt/java/jdk/bin:$PATH \
        # 映射端口取8085,也可以用常用的80和8080
        -p 8085:8085 \
        # 使用ubuntu20.04镜像
        ubuntu:20.04 /bin/bash

MySQL容器创建

MySQL同样弄了两个版本,一个是最常用的5.7,一个是MySQL8,也是纯测试用。

由于我租的服务器资源有限,这里显式指定了容器的内存(512 M)和可用的 cpu (0.5个核的算力),防止日后占用过多资源。

# 5.7
docker run -d --name mysql57 \
    -e MYSQL_ROOT_PASSWORD=root \
    # 将容器的3306映射到宿主机的3306,方便以后用工具连接查看
    -p 3306:3306 \
    -v /home/workspace/mysql/mysql57:/var/lib/mysql \
    --memory="512m" \
    --cpus="0.5" \
    mysql:5.7
    
# 8.0
docker run -d --name mysql80 \
    -e MYSQL_ROOT_PASSWORD=root \
    # 将容器的3306映射到宿主机的3307,方便以后用工具连接查看
    -p 3307:3306 \
    -v /home/workspace/mysql/mysql80:/var/lib/mysql \
    --memory="512m" \
    --cpus="0.5" \
    mysql:8.0

--memory="512m" 是容器内所有进程(包括MySQL及其子进程)的总内存上限,当容器的内存使用量超过 512 MB 时,Docker 会触发内存不足终止机制(OOM Killer),强制终止容器进程(显示为容器崩溃或退出)。

这个限制仅包括物理内存,不包括交换分区(Swap)。如需限制交换分区,需额外配置 --memory-swap

交换分区(Swap Space)  是什么?

是操作系统(如 Linux)中一种特殊的磁盘空间,用于在物理内存(RAM)不足时,临时存储被换出的内存页(即不活跃的进程数据)。它的核心作用是 扩展虚拟内存 ,防止系统因内存耗尽而崩溃。

docker 的 memory-swap 需要结合宿主机的 swap 配置启用,也需要这个容器已经配置了--memory。相关配置在官方文档中可以找到说明:https://docs.docker.com/engine/containers/resource_constraints/#–memory-swap-details

MySQL 8.0 默认配置可能默认需要较多内存(如 innodb_buffer_pool_size 默认 128MB),建议根据业务调整 MySQL 配置以避免内存不足。

可通过 docker stats <容器名> 实时监控容器的内存和 CPU 使用情况。

Redis 和 RabbitMQ 容器创建

如果你的应用没用到这两个,没关系,早晚会用到的(

# Redis 创建,同样限制了最大可用内存和 CPU 计算资源
docker run -d --name redis \
    -p 6379:6379 \
    --memory 100m \
    --cpus 0.1 \
    redis:alpine

# RabbitMQ 创建,同样限制了最大可用内存和 CPU 计算资源
docker run -d --name rabbitmq \
    -p 15672:15672 \
    --memory 200m \
    --cpus 0.2 \
    rabbitmq:management-alpine

nginx 配置

nginx 基本就是配置文件的编写。

docker run -d --name nginx-proxy \
        --network my-network \
        -p 80:80 \
        -p 443:443 \
        -v /home/workspace/nginx/:/home/workspace/nginx \
        -v /home/workspace/nginx/nginx.conf:/etc/nginx/nginx.conf \
        nginx

--network 是 docker 网络的配置,这点后面会说,并且前面几个容器也需要补充配置,好在不需要删除容器,有单独将容器添加到网络里的命令。

nginx 绑定的配置文件里需要下面这些东西。

// nginx 的配置文件其实不是json格式,但代码块用json有比较方便的颜色区分……
events {
    worker_connections 1024;
}

http {
    server {
        listen 80;# 监听端口
        server_name 云服务器IP;
        // 下面这个 // 不是注释的意思,别删错了
        return 301 https://$host$request_uri;
    }
    server{
        listen 443 ssl;
        server_name 云服务器IP;

        //这两个是ssl证书地址,有专门用于测试的获取渠道
        //正规的一般需要付费购买,且前提是有域名
        ssl_certificate /home/workspace/nginx/ssl/cert.pem;
        ssl_certificate_key /home/workspace/nginx/ssl/key.pem;

        ssl_protocols TLSv1.2 TLSv1.3;
        ssl_ciphers HIGH:!aNULL:!MD5;

        location / {
            proxy_pass http://apps(部署应用的容器名):8085;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
        }
    }
}

本地创建ssl测试证书的命令是:
openssl req -x509 -newkey rsa:4096 -nodes -out cert.pem -keyout key.pem -days 365,生成的两个文件放到前面配置的 ssl_certificate 和 ssl_certificate_key 的路径下就行。

上面的 nginx 配置实际上只是转发云服务器的80端口到指定的有且只有一个的应用容器上,但在分布式情况下,应用容器不会只有一个,因此你需要的是下面字更多的版本。

events {
    worker_connections 1024;
}

http {
    upstream app_servers{
        server apps1:8085;
        server apps2:8085;
        server apps3:8085;
    }

    server {
        listen 80;
        server_name 云服务器IP;
        // 下面这个 // 不是注释的意思,别删错了
        return 301 https://$host$request_uri;
    }
    server{
        listen 443 ssl;
        server_name 云服务器IP;

        ssl_certificate /home/workspace/nginx/ssl/cert.pem;
        ssl_certificate_key /home/workspace/nginx/ssl/key.pem;

        ssl_protocols TLSv1.2 TLSv1.3;
        ssl_ciphers HIGH:!aNULL:!MD5;

        location / {
            // 下面这个 // 不是注释的意思,别删错了
            proxy_pass http://app_servers;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
        }
    }
}

nginx 的配置文件修改后要生效只需要简单地重启容器docker start nginx-proxy

到这里一个极简的分布式环境差不多就搞好了,可以开始玩了(。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2395966.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

XCTF-web-fileclude

解析如下 <?php include("flag.php"); // 包含敏感文件&#xff08;通常包含CTF挑战的flag&#xff09; highlight_file(__FILE__); // 高亮显示当前PHP文件源代码&#xff08;方便查看代码逻辑&#xff09;if(isset($_GET["file1"]…

OpenShift AI - 启用过时版本的 Notebook 镜像

《OpenShift / RHEL / DevSecOps 汇总目录》 说明&#xff1a;本文已经在 OpenShift 4.18 OpenShift AI 2.19 的环境中验证 文章目录 查看可用 Notebook 镜像控制台查看命令行查看 Notebook 镜像、Image Stream 和 Image Registry Repository 对应关系启用老版本的 Notebook 镜…

Redis 缓存穿透、缓存击穿、缓存雪崩详解与解决方案

在分布式系统中&#xff0c;Redis 凭借高性能和高并发处理能力&#xff0c;成为常用的缓存组件。然而&#xff0c;在实际应用中&#xff0c;缓存穿透、缓存击穿、缓存雪崩这三大问题会严重影响系统的性能与稳定性。本文将详细解析这三个问题的成因&#xff0c;并提供对应的解决…

DQN和DDQN(进阶版)

来源&#xff1a; *《第五章 深度强化学习 Q网络》.ppt --周炜星、谢文杰 一、前言 Q表格、Q网络与策略函数 Q表格是有限的离散的&#xff0c;而神经网络可以是无限的。 对于动作有限的智能体来说&#xff0c;使用Q网络获得当下状态的对于每个动作的 状态-动作值 。那么 a…

【组件】翻牌器效果

目录 效果组件代码背景素材 效果 组件代码 <template><divclass"card-flop":style"{height: typeof height number ? ${height}px : height,--box-width: typeof boxWidth number ? ${boxWidth}px : boxWidth,--box-height: typeof boxHeight nu…

CentOS 7 环境中部署 LNMP(Linux + Nginx + MySQL 5.7 + PHP)

在 CentOS 7 环境中部署 LNMP&#xff08;Linux Nginx MySQL 5.7 PHP&#xff09; 环境的详细步骤如下。此方案确保各组件版本兼容&#xff0c;并提供完整的配置验证流程。 1. 更新系统 sudo yum update -y 2. 安装 MySQL 5.7 2.1 添加 MySQL 官方 YUM 仓库 由于MySQL并不…

NX811NX816美光颗粒固态NX840NX845

NX811NX816美光颗粒固态NX840NX845 美光NX系列固态硬盘颗粒深度解析&#xff1a;技术、性能与市场全景透视 一、技术架构与核心特性解析 1. NX811/NX816&#xff1a;入门级市场的平衡之选 技术定位&#xff1a;基于176层TLC&#xff08;Triple-Level Cell&#xff09;3D NAN…

捋捋wireshark

本猿搬砖时会用到wireshark分析pcap包&#xff0c;但频率不高&#xff0c;记过一些笔记&#xff0c;今天捋捋&#xff0c;希望能给初学者节省一点时间。 wireshark是个网络封包分析软件&#xff08;network packet analyzer&#xff09;&#xff0c;可以用来抓流量包&#xff…

c++学习之---模版

目录 一、函数模板&#xff1a; 1、基本定义格式&#xff1a; 2、模版函数的优先匹配原则&#xff1a; 二、类模板&#xff1a; 1、基本定义格式&#xff1a; 2、类模版的优先匹配原则&#xff08;有坑哦&#xff09;&#xff1a; 3、缺省值的设置&#xff1a; 4、ty…

第十六章 EMQX黑名单与连接抖动检测

系列文章目录 第一章 总体概述 第二章 在实体机上安装ubuntu 第三章 Windows远程连接ubuntu 第四章 使用Docker安装和运行EMQX 第五章 Docker卸载EMQX 第六章 EMQX客户端MQTTX Desktop的安装与使用 第七章 EMQX客户端MQTTX CLI的安装与使用 第八章 Wireshark工具的安装与使用 …

新编辑器编写指南--给自己的备忘

欢迎使用Markdown编辑器 你好&#xff01; 这是你第一次使用 Markdown编辑器 所展示的欢迎页。如果你想学习如何使用Markdown编辑器, 可以仔细阅读这篇文章&#xff0c;了解一下Markdown的基本语法知识。 新的改变 我们对Markdown编辑器进行了一些功能拓展与语法支持&#x…

鸿蒙网络数据传输案例实战

一、案例效果截图 二、案例运用到的知识点 核心知识点 网络连接管理&#xff1a;connection模块HTTP数据请求&#xff1a;http模块RPC数据请求&#xff1a;rcp模块文件管理能力&#xff1a;fileIo模块、fileUri模块 其他知识点 ArkTS 语言基础V2版状态管理&#xff1a;Comp…

【JavaEE】-- 网络原理

文章目录 1. 网络发展史1.1 广域网1.2 局域网 2. 网络通信基础2.1 IP地址2.2 端口号2.3 认识协议2.4 五元组2.5 协议分层2.5.1 分层的作用2.5.2 OSI七层模型&#xff08;教科书&#xff09;2.5.3 TCP/IP五层&#xff08;或四层&#xff09;模型&#xff08;工业中常用&#xff…

1.RV1126-OPENCV 交叉编译

一.下载opencv-3.4.16.zip到自己想装的目录下 二.解压并且打开 opencv 目录 先用 unzip opencv-3.4.16.zip 来解压 opencv 的压缩包&#xff0c;并且进入 opencv 目录(cd opencv-3.4.16) 三. 修改 opencv 的 cmake 脚本的内容 先 cd platforms/linux 然后修改 arm-gnueabi.to…

PySide6 GUI 学习笔记——常用类及控件使用方法(标签控件QLabel)

文章目录 标签控件QLabel及其应用举例标签控件QLabel的常用方法及信号应用举例Python 代码示例1Python 代码示例2 小结 标签控件QLabel及其应用举例 QLabel 是 PySide6.QtWidgets 模块中的一个控件&#xff0c;用于在界面上显示文本或图像。它常用于作为标签、提示信息或图片展…

CSS (mask)实现服装动态换色:创意与技术的完美融合

在网页开发中&#xff0c;我们常常会遇到需要对图片元素进行个性化处理的需求&#xff0c;比如改变图片中特定部分的颜色。今天&#xff0c;我们就来探讨一种通过 CSS 和 JavaScript 结合&#xff0c;实现服装动态换色的有趣方法。 一、代码整体结构分析 上述代码构建了一个完…

基于51单片机的音乐盒汽车喇叭调音量proteus仿真

地址&#xff1a; https://pan.baidu.com/s/1l3CSSMi4uMV5-XLefnKoSg 提取码&#xff1a;1234 仿真图&#xff1a; 芯片/模块的特点&#xff1a; AT89C52/AT89C51简介&#xff1a; AT89C51 是一款常用的 8 位单片机&#xff0c;由 Atmel 公司&#xff08;现已被 Microchip 收…

彻底理解Spring三级缓存机制

文章目录 前言一、Spring解决循环依赖时&#xff0c;为什么要使用三级缓存&#xff1f; 前言 Spring解决循环依赖的手段&#xff0c;是通过三级缓存&#xff1a; singletonObjects&#xff1a;存放所有生命周期完整的单例对象。&#xff08;一级缓存&#xff09;earlySingleto…

【产品经理从0到1】自媒体端产品设计

后台的定义 “后台” 与“前台”都是相对独立的平台&#xff0c;前台是服务于互联网用户的平台 &#xff0c;后台主要是支撑前台页面内容、数据及对前台业务情况的统计分析的系统&#xff1b; 后台与前台的区别 第1&#xff1a;使用用户不同 前台用户&#xff1a;互联网用户…

017搜索之深度优先DFS——算法备赛

深度优先搜索 如果说广度优先搜索是逐层扩散&#xff0c;那深度优先搜索就是一条道走到黑。 深度优先遍历是用递归实现的&#xff0c;预定一条顺序规则&#xff08;如上下左右顺序&#xff09; &#xff0c;一直往第一个方向搜索直到走到尽头或不满足要求后返回上一个叉路口按…