在这个简短的演示中,我们将在同一台计算机 (localhost) 上设置并运行 WildFly 的三个实例。它们一起形成一个簇。这是一种相当经典的设置,应用程序服务器需要同步其应用程序会话的内容,以确保在其中一个实例发生故障时进行故障转移。此配置保证,如果一个实例在处理请求时失败,另一个实例可以接替工作而不会丢失任何数据。请注意,我们将使用多播来发现集群的成员,并确保集群的形成是完全自动化和动态的。
为 WildFly 安装 Ansible 及其集合
在使用包管理器的 Linux 系统上,安装 Ansible 非常简单:
sudo dnf install ansible-core
请参阅在线文档以了解如何在其他操作系统上进行安装。请注意,此演示假设您在 Linux 系统上运行 Ansible 控制器和目标(在我们的例子中是同一台机器)。但是,经过一些调整,它应该可以在任何其他操作系统上运行。
在继续之前,请仔细检查您是否正在运行足够新的 Ansible 版本(2.14 或更高版本即可,但 2.9 是最低限度):
ansible [核心 2.15.3]
配置文件= /etc/ansible/ansible.cfg
配置的模块搜索路径 = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
ansible python 模块位置 = /usr/lib/python3.11/site-packages/ansible
ansible集合位置= /root/.ansible/collections:/usr/share/ansible/collections
可执行位置 = /usr/bin/ansible
python版本= 3.11.2(主要,2023年6月6日,07:39:01)[GCC 8.5.0 20210514(Red Hat 8.5.0-18)](/usr/bin/python3.11)
金贾版本 = 3.1.2
libyaml = True
准备 Ansible 环境的下一步也是最后一步是在控制器(将运行 Ansible 的计算机)上安装 WildFly 的 Ansible 集合:
# ansible-galaxy 集合安装 middleware_automation.wildfly
启动 Galaxy Collection 安装过程
进程安装依赖关系图
开始收集安装过程
下载 https://galaxy.ansible.com/api/v3/plugin/ansible/content/published/collections/artifacts/middleware_automation-wildfly-1.4.3.tar.gz 到 /root/.ansible/tmp/ansible-local -355dkk9kf5/tmpc2qtag11/middleware_automation-wildfly-1.4.3-9propr_x
下载 https://galaxy.ansible.com/api/v3/plugin/ansible/content/published/collections/artifacts/ansible-posix-1.5.4.tar.gz 到 /root/.ansible/tmp/ansible-local -355dkk9kf5/tmpc2qtag11/ansible-posix-1.5.4-pq0cq2mn
将“middleware_automation.wildfly:1.4.3”安装到“/root/.ansible/collections/ansible_collections/middleware_automation/wildfly”
middleware_automation.wildfly:1.4.3安装成功
将 'ansible.posix:1.5.4' 安装到 '/root/.ansible/collections/ansible_collections/ansible/posix'
下载 https://galaxy.ansible.com/api/v3/plugin/ansible/content/published/collections/artifacts/middleware_automation-common-1.1.4.tar.gz 到 /root/.ansible/tmp/ansible-local -355dkk9kf5/tmpc2qtag11/middleware_automation-common-1.1.4-nks7pvy7
ansible.posix:1.5.4 安装成功
将“middleware_automation.common:1.1.4”安装到“/root/.ansible/collections/ansible_collections/middleware_automation/common”
middleware_automation.common:1.1.4安装成功
设置 WildFly 集群
为了简单起见,并允许您在一台计算机(物理或虚拟)甚至容器上重现此演示,我们选择在一个目标上部署三个实例。我们选择localhost
作为目标,这样演示甚至可以在没有远程主机的情况下执行。
设置 WildFly 集群基本上有两个步骤:
- 在目标主机上安装 WildFly(此处为
localhost
)。这意味着从该网站下载存档并将存档解压到适当的目录 (JBOSS_HOME
)。这些任务由 WildFly Ansible 集合提供的wildfly_install
角色处理。 - 创建配置文件以运行 WildFly 的多个实例。由于我们在单个主机上运行多个实例,因此您还需要确保每个实例都有自己的子目录和端口集,以便实例可以共存和通信。幸运的是,此功能是由 Ansible 集合中名为
wildfly_systemd
的角色提供的。
Ansible Playbook 安装 WildFly
这是我们将用来部署集群的剧本。它的内容相对来说是不言自明的,至少如果您对 Ansible 语法有些熟悉的话。
- name: "WildFly 安装和配置"
主机:“{{hosts_group_name | default('localhost') }}”
变成:是
变量:
wildfly_install_workdir: '/opt/'
wildfly_config_base:独立-ha.xml
wildfly_版本:30.0.1.Final
wildfly_java_package_name:java-11-openjdk-headless.x86_64
wildfly_home: "/opt/wildfly-{{ wildfly_version }}"
实例_http_端口:
- 8080
- 8180
- 8280
应用程序:
名称:'info-1.2.war'
网址:'https://drive.google.com/uc?export=download&id=13K7RCqccgH4zAU1RfOjYMehNaHB0A3Iq'
收藏:
- middleware_automation.wildfly
角色:
- 角色:wildfly_install
任务:
- 名称:“设置 WildFly 实例 {{ item }}。”
ansible.builtin.include_role:
名称:wildfly_systemd
变量:
wildfly_config_base: 'standalone-ha.xml'
wildfly_instance_id:“{{项目}}”
instance_name:“wildfly-{{ wildfly_instance_id }}”
wildfly_config_name:“{{instance_name}}.xml”
wildfly_basedir_prefix:“/ opt / {{实例名称}}”
service_systemd_env_file: "/etc/wildfly-{{ item }}.conf"
service_systemd_conf_file:“/usr/lib/systemd/system/wildfly-{{ item }}.service”
循环:“{{范围(0,3)|列表}}”
- name:“等待每个实例 HTTP 端口变得可用。”
ansible.builtin.wait_for:
端口:“{{项目}}”
循环:“{{instance_http_ports}}”
- 名称:“检查 WildFly 服务器是否正在运行且可访问。”
ansible.builtin.get_url:
url: "http://localhost:{{ 端口 }}/"
目标:“/opt/{{ 端口 }}”
循环:“{{instance_http_ports}}”
循环控制:
Loop_var:端口
简而言之,本剧本首先使用 WildFly 的 Ansible 集合通过 wildfly_install
角色来安装应用程序服务器。这将下载所有工件、创建所需的系统组和用户、安装依赖项(解压缩)等等。执行结束时,在目标主机上运行 WildFly 所需的所有花絮都已安装,但服务器尚未运行。这就是下一步发生的事情。
在剧本的任务部分,我们调用集合提供的另一个角色:wildfly_systemd
。该角色将负责将 WildFly 作为常规系统服务集成到服务管理器中。在这里,我们使用循环来确保我们创建的不是一个,而是三个不同的服务。每个都具有相同的配置 (standalone-ha.xml
),但在不同的端口上运行,使用一组不同的目录来存储其数据。
运行剧本!
现在,让我们运行 Ansible playbook 并观察其输出:
请注意,剧本并没有那么长,但它对我们有很多帮助。它执行近 100 个不同的任务,首先自动安装依赖项,包括 WildFly 所需的 JVM,并下载其二进制文件。 wildfly_systemd
角色的作用甚至更多,可以轻松设置三个不同的服务,每个服务都有自己的一组端口和目录布局来存储特定于实例的数据。
更好的是,WildFly 安装不会重复。所有二进制文件都位于 /opt/wildfly-27.0.1 目录下,但每个实例的所有数据文件都存储在单独的文件夹中。这意味着我们只需要更新一次二进制文件,然后重新启动实例即可部署补丁或升级到新版本的 WildFly。
最重要的是,我们将实例配置为使用 standalone-ha.xml 配置作为基准,因此它们已经设置为集群。
检查一切是否按预期工作
确认 playbook 确实安装了 WildFly 并启动了应用程序服务器的三个实例的最简单方法是使用 systemctl
命令检查关联服务状态:
# systemctl status wildfly-0
● wildfly-0.service - JBoss EAP(独立模式)
已加载:已加载(/usr/lib/systemd/system/wildfly-0.service;启用;供应商预设:禁用)
活跃:自 UTC 2024-01-18 星期四 07:01:44 起活跃(运行); 5 分钟前
主PID:884(standalone.sh)
任务:89(限制:1638)
内存:456.3M
CGroup:/system.slice/wildfly-0.service
├─ 884 /bin/sh /opt/wildfly-30.0.1.Final/bin/standalone.sh -c wildfly-0.xml -b 0.0.0.0 -bmanagement 127.0.0.1 -Djboss.bind.address.private=127.0 .0.1 -Djboss.default.multicast.address=230.0.0.4 -Djboss.server.config.dir=/opt/wildfly-30.0.1.Final/standalone/configuration/ -Djboss.server.base.dir=/opt/ wildfly-00 -Djboss.tx.node.id=wildfly-0 -Djboss.socket.binding.port-offset=0 -Djboss.node.name=wildfly-0 -Dwildfly.statistics-enabled=false
└─1044 /etc/alternatives/jre_11/bin/java -D[独立] -Djdk.serialFilter=maxbytes=10485760;maxdepth=128;maxarray=100000;maxrefs=300000 -Xmx1024M -Xms512M --add-exports=java.桌面/sun.awt=全部未命名 --add-exports=java.naming/com.sun.jndi.ldap=全部未命名 --add-exports=java.naming/com.sun.jndi.url.ldap=全部未命名 --add-exports=java.naming/com.sun.jndi.url.ldaps=全部未命名 --add-exports=jdk.naming.dns/com.sun.jndi.dns=全部未命名 - -add-opens=java.base/com.sun.net.ssl.internal.ssl=ALL-UNNAMED --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base /java.lang.invoke=ALL-UNNAMED --add-opens=java.base/java.lang.reflect=ALL-UNNAMED --add-opens=java.base/java.io=ALL-UNNAMED --add- opens=java.base/java.net=ALL-UNNAMED --add-opens=java.base/java.security=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add -opens=java.base/java.util.concurrent=ALL-UNNAMED --add-opens=java.management/javax.management=ALL-UNNAMED --add-opens=java.naming/javax.naming=ALL-UNNAMED -Dorg.jboss.boot.log.file=/opt/wildfly-00/log/server.log -Dlogging.configuration=文件:/opt/wildfly-30.0.1.Final/standalone/configuration/logging.properties -jar /opt/wildfly-30.0.1.Final/jboss-modules.jar -mp /opt/wildfly-30.0.1.Final/modules org.jboss.as.standalone -Djboss.home.dir=/opt/wildfly-30.0 .1.最终-Djboss.server.base.dir=/opt/wildfly-00 -c wildfly-0.xml -b 0.0.0.0 -bmanagement 127.0.0.1 -Djboss.bind.address.private=127.0.0.1 -Djboss .default.multicast.address=230.0.0.4 -Djboss.server.config.dir=/opt/wildfly-30.0.1.Final/standalone/configuration/ -Djboss.server.base.dir=/opt/wildfly-00 - djboss.tx.node.id=wildfly-0 -Djboss.socket.binding.port-offset=0 -Djboss.node.name=wildfly-0 -Dwildfly.statistics-enabled=false
Jan 18 07:01:47 7c4a5dd056d1standalone.sh[1044]: 07:01:47,090 INFO [org.jboss.modcluster] (ServerService 线程池 -- 84) MODCLUSTER000032: 监听 /224.0.1.105:23364 上的代理广告
Jan 18 07:01:47 7c4a5dd056d1standalone.sh[1044]: 07:01:47,148 INFO [org.wildfly.extension.undertow](MSC 服务线程 1-4)WFLYUT0006:Undertow HTTPS 侦听器 https 侦听 [0:0 :0:0:0:0:0:0]:8443
Jan 18 07:01:47 7c4a5dd056d1standalone.sh[1044]: 07:01:47,149 INFO [org.jboss.as.ejb3](MSC 服务线程 1-3)WFLYEJB0493:Jakarta Enterprise Beans 子系统暂停完成
Jan 18 07:01:47 7c4a5dd056d1standalone.sh[1044]: 07:01:47,183 INFO [org.jboss.as.connector.subsystems.datasources](MSC 服务线程 1-2)WFLYJCA0001:绑定数据源 [java: jboss/数据源/ExampleDS]
Jan 18 07:01:47 7c4a5dd056d1standalone.sh[1044]: 07:01:47,246 INFO [org.jboss.as.server.deployment.scanner](MSC 服务线程 1-2)WFLYDS0013:为目录 /opt 启动 FileSystemDeploymentService /wildfly-00/部署
Jan 18 07:01:47 7c4a5dd056d1standalone.sh[1044]: 07:01:47,285 INFO [org.jboss.ws.common.management](MSC 服务线程 1-5)JBWS022052:启动 JBossWS 7.0.0.Final(阿帕奇CXF 4.0.0)
Jan 18 07:01:47 7c4a5dd056d1standalone.sh[1044]: 07:01:47,383 INFO [org.jboss.as.server](控制器启动线程)WFLYSRV0212:正在恢复服务器
Jan 18 07:01:47 7c4a5dd056d1standalone.sh[1044]: 07:01:47,388 INFO [org.jboss.as](控制器启动线程)WFLYSRV0060:Http 管理接口监听 http://127.0.0.1:9990/管理
Jan 18 07:01:47 7c4a5dd056d1standalone.sh[1044]: 07:01:47,388 INFO [org.jboss.as](控制器启动线程)WFLYSRV0051:管理控制台正在监听 http://127.0.0.1:9990
Jan 18 07:01:47 7c4a5dd056d1standalone.sh[1044]: 07:01:47,390 INFO [org.jboss.as](控制器启动线程)WFLYSRV0025:WildFly Full 30.0.1.Final(WildFly Core 22.0.2.Final) )在 2699 毫秒内启动 - 启动了 708 个服务中的 311 个(497 个服务是惰性的、被动的或按需的) - 使用的服务器配置文件:wildfly-0.xml
将应用程序部署到 WildFly 集群
现在,我们的三个 WildFly 正在运行,但集群尚未形成。事实上,没有应用程序,集群就没有存在的理由。让我们修改 Ansible 剧本,将一个简单的应用程序部署到所有实例;这将使我们能够检查集群是否按预期工作。为了实现这一目标,我们将利用 WildFly 集合提供的另一个角色:wildfly_utils
。
在我们的例子中,我们将使用 jboss_cli.yml 任务文件,它封装了 JBoss 命令行界面 (CLI) 查询的运行:
...
后任务:
- name: "确保已从 {{ app.url }} 检索 webapp {{ app.name }}。"
ansible.builtin.get_url:
网址:“{{app.url}}”
目标:“{{ wildfly_install_workdir }}/{{ app.name }}”
- 名称:“部署 web 应用程序”
ansible.builtin.include_role:
名称:wildfly_utils
任务来源:jboss_cli.yml
变量:
jboss_home:“{{wildfly_home}}”
查询:“'deploy --force {{ wildfly_install_workdir }}/{{ app.name }}'”
jboss_cli_controller_port:“{{项目}}”
环形:
- 9990
- 10090
- 10190
现在,我们将再次执行我们的剧本,以便将 Web 应用程序部署在所有实例上。一旦自动化成功完成,部署将触发集群的形成。
验证 WildFly 集群是否正在运行且应用程序是否已部署
您可以通过查看三个实例中任意一个的日志文件来验证集群的形成:
...
2022-12-23 15:02:08,252 INFO [org.infinispan.CLUSTER] (thread-7,ejb,jboss-eap-0) ISPN000094:收到通道 ejb 的新集群视图:[jboss-eap-0] (3 ) [jboss-eap-0, jboss-eap-1, jboss-eap-2]
...
使用 Ansible 集合作为 WildFly 的安装程序
最后备注:虽然该集合设计用于在 playbook 中使用,但您也可以使用提供的 playbook 直接安装 Wildfly:
$ ansible-playbook -i inventory middleware_automation.wildfly.playbook
结论
开始吧:通过一个简短的剧本,我们已经完全自动化了 WildFly 集群的部署!该剧本现在可以用于对付一台、两台、三台远程计算机,甚至数百台!我希望这篇文章能够提供丰富的信息,并说服您使用 Ansible 来设置您自己的 WildFly 服务器!