Linux相关知识的第二十回合

Linux相关知识的第二十回合

MySQL的高可性解决方案MHA实战

配置hosts文件

# 在主从及管理主机上添加hosts配置文件
cat /etc/hosts
192.168.168.66 master
192.168.168.38 slave1
192.168.168.39 slave2
192.168.168.67 manager

配置ssh免密钥登录

# 创建密钥对
ssh-keygen -t rsa
# 将公钥复制到其他主机上
for i in master slave1 slave2 manager;do ssh-copy-id $i;done

配置epel源并安装MHA所需要的依赖包

# 在所有的节点都需要安装,包括MHA管理节点及MySQL的master、slave节点
yum -y install epel-release
yum makecache all
# 安装依赖
yum -y install perl-DBD-MySQL perl-Config-Tiny perl-Log-Dispatch perl-ParallelForkManager perl-Config-IniFiles ncftp perl-Params-Validate perl-CPAN perl-TestMock-LWP.noarch perl-LWP-Authen-Negotiate.noarch perl-devel perl-ExtUtils-CBuilder perl-ExtUtils-MakeMaker

配置主从复制

参考之前的文档,在此不赘述

# 主从复制完成后,创建MHA的管理账号
MariaDB root@(none):(none)> grant all on *.* to manager@'192.168.20.%' identified by 'e3w2q1';

安装MHA-node

# MHA-node在所有的节点都需要安装
# MHA-node的RPM包下载地址
https://github.com/yoshinorim/mha4mysql-node/releases
cd /data/soft
wget https://github.com/yoshinorim/mha4mysql-node/releases/download/v0.58/mha4mysql-node-0.58-0.el7.centos.noarch.rpm
rpm -ivh mha4mysql-node-0.58-0.el7.centos.noarch.rpm

安装MHA-manager

# 在MHA的管理节点上安装MHA-manager
# MHA-manager的RPM包下载地址
https://github.com/yoshinorim/mha4mysql-manager/releases
cd /data/soft
wget https://github.com/yoshinorim/mha4mysql-manager/releases/download/v0.58/mha4mysql-manager-0.58-0.el7.centos.noarch.rpm
rpm -ivh mha4mysql-manager-0.58-0.el7.centos.noarch.rpm

配置MHA-manager

# 创建配置文件
mkdir /etc/mastermha/
vim /etc/mastermha/app1.cnf
######################################################################
[server default]
# 指定manager管理数据库节点所使用的用户名
user=mhauser
# 指定manager管理数据库节点所使用的密码
password=e3w2q1
# 指定工作目录
manager_workdir=/data/mastermha/app1/
# 指定日志文件目录
manager_log=/data/mastermha/app1/manager.log
remote_workdir=/data/mastermha/app1/
# 指定ssh免密钥登录的系统用户
ssh_user=root
# 指定ssh端口
ssh_port=10022
# 指定用于主从同步的用户名
repl_user=repluser
# 指定同步用户的密码
repl_password=Q1w2e3
# 设置监控Master主库的时间间隔,默认为3秒;尝试3次没有回应后,自动进行切换
ping_interval=1

[server1]
hostname=192.168.168.66
# 指定Master保存二进制日志的路径,以便MHA可以找到master的日志
master_binlog_dir=/data/mysql/logs
# 设置为候选master,设置该参数后,发生主从切换以后,将从此库提升为主库
candidate_master=1

[server2]
hostname=192.168.168.38
master_binlog_dir=/data/mysql/logs
candidate_master=1

[server3]
hostname=192.168.168.39
no_master=1
######################################################################

# 启动前检验
# 验证ssh有效性
masterha_check_ssh --conf=/etc/mastermha/app1.cnf
# 验证集群复制的有效性
masterha_check_repl --conf=/etc/masterha/app1.cnf

# 启动MHA管理服务
nohup masterha_manager --conf=/etc/masterha/app1.cnf &> /data/logs/mha_manager.log &
# PS:可以多次执行启动服务命令,指定不同的配置文件,以便监控多个MySQL集群

# 查看MHA运行状态
masterha_check_status --conf=/etc/mastermha/app1.cnf

参考文献

CentOS7下RPM安装MHA0.58

Ansible常用模块总结

ping模块

测试主机是否是通的,用法很简单,不涉及参数:

ansible test -m ping

setup模块

setup模块,主要用于获取主机信息,在playbooks里经常会用到的一个参数gather_facts就与该模块相关,当“gather_facts = True” 时,playbooks中可以调用setup模块中的内置变量
setup模块下经常使用的一个参数是filter参数,具体使用示例如下:

# 查看远程主机的信息
ansible svn -m setup -a 'filter=ansible_distribution' 
# 查看远程主机内存信息        
ansible 10.212.52.252 -m setup -a 'filter=ansible_*_mb' 
# 将所有主机的信息输入到/tmp/facts目录下,每台主机的信息输入到主机名文件中(/etc/ansible/hosts里的主机名)      
 ansible all -m setup --tree /tmp/facts  

file模块

file模块主要用于远程主机上的文件操作,file模块常用的参数:

  • force:需要在两种情况下强制创建软链接,一种是源文件不存在但之后会建立的情况下;另一种是目标软链接已存在,需要先取消之前的软链,然后创建新的软链,有两个选项:yes|no
  • group:定义文件/目录的属组
  • mode:定义文件/目录的权限
  • owner:定义文件/目录的属主
  • path:必选项,定义文件/目录的路径
  • recurse:递归的设置文件的属性,只对目录有效
  • src:要被链接的源文件的路径,只应用于state=link的情况
  • dest:被链接到的路径,只应用于state=link的情况
  • state:
    directory:如果目录不存在,创建目录
    file:即使文件不存在,也不会被创建
    link:创建软链接
    hard:创建硬链接
    touch:如果文件不存在,则会创建一个新的文件,如果文件或目录已存在,则更新其最后修改时间
    absent:删除目录、文件或者取消链接文件
# 在tmp目录下创建一个fstab的软连接到/etc/fstab
ansible web -m file -a "src=/etc/fstab dest=/tmp/fstab state=link"  
# 删除tmp目录下的fstab   
ansible web -m file -a "path=/tmp/fstab state=absent"   
# 在tmp目录下创建一个test文件               
ansible web -m file -a "path=/tmp/test state=touch" 
# 在tmp目录下创建一个dir1的目录,属主跟属组:root,权限777                   
ansible web -m file -a "path=/tmp/dir1 state=directory 
owner=root group=root mode=777"      

copy模块

复制文件到远程主机,copy模块包含如下选项:

  • backup:在覆盖之前将原文件备份,备份文件包含时间信息。有两个选项:yes|no
  • content:用于替代"src",可以直接设定指定文件的值
  • dest:必选项 要将源文件复制到的远程主机的绝对路径,如果源文件是一个目录,那么该路径也必须是个目录
  • group:定义文件/目录的属组
  • mode:定义文件/目录的权限
  • owner:定义文件/目录的属主
  • directory_mode:递归的设定目录的权限,默认为系统默认权限
  • force:如果目标主机包含该文件,但内容不同,如果设置为yes,则强制覆盖,如果为no,则只有当目标主机的目标位置不存在该文件时,才复制。默认为yes
  • others:所有的file模块里的选项都可以在这里使用
  • src:要复制到远程主机的文件在本地的地址,可以是绝对路径,也可以是相对路径。如果路径是一个目录,它将递归复制。在这种情况下,如果路径使用"/“来结尾,则只复制目录里的内容,如果没有使用”/"来结尾,则包含目录在内的整个内容全部复制,类似于rsync
  • validate :The validation command to run before copying into place. The path to the file to validate is passed in via ‘%s’ which must be present as in the visudo example below.
# 将本机的/srv/myfiles/foo.conf复制到远程主机的/etc/foo.conf,属主跟属组为foo,权限为644
ansible test -m copy -a "src=/srv/myfiles/foo.conf dest=/etc/foo.conf owner=foo group=foo mode=0644"
# 将本机的/mine/ntp.conf复制到远程主机的/mine/ntp.conf,属主跟属组为foo,权限为644,如果远程主机有这个文件先做备份
ansible test -m copy -a "src=/mine/ntp.conf dest=/etc/ntp.conf owner=root group=root mode=644 backup=yes"
# 将本机的/mine/sudoers复制到远程主机的/etc/sudoers,如果有语法错误将不被保存(加入validate的验证,比如sudo文件如果改错了,可能影响整个系统的管理,加入验证之后,如果修改的sudo文件格式错误,将不会保存) 
ansible test -m copy -a "src=/mine/sudoers dest=/etc/sudoers validate='visudo -cf %s'"

template模块

可以将带有变量的配置文件(jinja2)传递到远程主机,template模块包括如下选项:

  • backup: 在覆盖之前将原文件备份,有两个选项:yes|no
  • dest:必选项 要将源文件复制到的远程主机的绝对路径
  • group:定义文件/目录的属组
  • mode:定义文件/目录的权限
  • owner:定义文件/目录的属主
  • src: 必选项 jinja2模板文件的路径,可以是相对或绝对的路径
  • validate:The validation command to run before copying into place. The path to the file to validate is passed in via ‘%s’ which must be present as in the example below. The command is passed securely so shell features like expansion and pipes won’t work.
# 将模板文件复制到远程主机的/etc/file.conf,属主为bin,属组为wheel,权限为644(template模板用于ansible-playbook)
- template:
    src: /mytemplates/foo.j2
    dest: /etc/file.conf
    owner: bin
    group: wheel
    mode: "u=rw,g=r,o=r"
# 从模板创建DOS样式的文本文件
- template:
    src: config.ini.j2
    dest: /share/windows/config.ini
    newline_sequence: '\r\n'
# 使用visudo验证后,将新的sudoers文件复制到远程主机
- template:
    src: /mine/sudoers
    dest: /etc/sudoers
    validate: '/usr/sbin/visudo -cf %s'
# 安全地更新sshd配置文件,避免锁定自己
- template:
    src: etc/ssh/sshd_config.j2
    dest: /etc/ssh/sshd_config
    owner: root
    group: root
    mode: '0600'
    validate: /usr/sbin/sshd -t -f %s
    backup: yes

service模块

用于管理远程主机上的服务,该模块包含如下选项:

  • arguments:给命令行提供一些选项,表示向命令行传递参数
  • enabled:是否开机启动 yes|no
  • name:必选项,服务名称
  • pattern:定义一个模式,如果通过status指令来查看服务的状态时,没有响应,就会通过ps指令在进程中根据该模式进行查找,如果匹配到,则认为该服务依然在运行
  • runlevel:运行级别
  • sleep:如果执行了restarted,在则stop和start之间沉睡几秒钟
  • state:对当前服务执行启动,停止、重启、重新加载等操作(started,stopped,restarted,reloaded)
# 启动httpd服务并设置为开机自启动
ansible test -m service -a "name=httpd state=started enabled=yes"
# 如果/usr/bin/foo有这个目录,则启动
asnible test -m service -a "name=foo pattern=/usr/bin/foo state=started"
# 重启eth0网卡
ansible test -m service -a "name=network state=restarted args=eth0"

cron模块

用于管理远程主机的定时任务的,该模块包含如下选项:

  • backup:对远程主机上的原任务计划内容修改之前做备份
  • cron_file:如果指定该选项,则用该文件替换远程主机上的cron.d目录下的用户的任务计划
  • day:日(1-31,/2,……)
  • hour:小时(0-23,/2,……)
  • minute:分钟(0-59,/2,……)
  • month:月(1-12,/2,……)
  • weekday:周(0-7,*,……)
  • job:要执行的任务,依赖于state=present
  • name:该任务的描述
  • special_time:指定什么时候执行,参数:reboot,yearly,annually,monthly,weekly,daily,hourly
  • state:确认该任务计划是创建还是删除 present(创建)|absent(删除)
  • user:以哪个用户的身份执行
# 当远程主机重启的时候,执行job.sh这个脚本
ansible test -m cron -a 'name="a job for reboot" special_time=reboot job="/some/job.sh"'
# 添加这个计划任务之前,先备份之前的计划任务。然后添加每天2点跟5点执行ls -alh这个命令
ansible test -m cron  -a 'backup="True" name="test" minute="0" hour="5,2" job="ls -alh > /dev/null"'
# 将ansible_yum-autoupdate任务删除
ansilbe test -m cron -a 'cron_file=ansible_yum-autoupdate state=absent'
# 将每分钟执行的ntpdate的定时任务删除,注意执行删除的时候,必须要满足name跟job两个条件,才可以执行删除任务
ansible test -m cron -a 'name=None job="/usr/sbin/ntpdate ch.pool.ntp.org >/dev/null 2>&1" state=absent'

filesystem模块

在块设备上创建文件系统,该模块包含如下选项:

  • dev:目标块设备
  • force:在一个已有文件系统 的设备上强制创建
  • fstype:文件系统的类型
  • opts:传递给mkfs命令的选项
ansible test -m filesystem -a 'fstype=ext2 dev=/dev/sdb1 force=yes'
ansible test -m filesystem -a 'fstype=ext4 dev=/dev/sdb1 opts="-cc"'

synchronize模块

使用rsync同步文件,该模块包含如下选项:

  • archive: 归档,相当于同时开启recursive(递归)、links、perms、times、owner、group、-D选项都为yes ,默认该项为开启
  • checksum: 跳过检测sum值,默认关闭
  • copy_links:复制链接文件,默认为no ,注意后面还有一个links参数
  • enablerepo:启用某个源
  • delete: 删除不存在的文件,默认no
  • dest:目录路径
  • dest_port:默认目录主机上的端口 ,默认是22,走的ssh协议
  • dirs:传速目录不进行递归,默认为no,即进行目录递归
  • rsync_opts:rsync参数部分
  • set_remote_user:主要用于/etc/ansible/hosts中定义或默认使用的用户与rsync使用的用户不同的情况
  • mode: push或pull 模块,push模的话,一般用于从本机向远程主机上传文件,pull 模式用于从远程主机上取文件
ansible all -m synchronize -a 'src=some/relative/path dest=/some/absolute/path rsync_path="sudo rsync"'
ansible all -m synchronize -a 'src=some/relative/path dest=/some/absolute/path archive=no links=yes'
ansible all -m synchronize -a 'src=some/relative/path dest=/some/absolute/path checksum=yes times=no'
ansible all -m synchronize -a 'src=/tmp/helloworld dest=/var/www/helloword rsync_opts=--no-motd,--exclude=.git mode=pull'

yum模块

使用yum包管理器来管理软件包,该模块包含如下选项:

  • config_file:yum的配置文件
  • disable_gpg_check:关闭gpg_check
  • disablerepo:不启用某个源
  • enablerepo:启用某个源
  • name:要进行操作的软件包的名字,也可以传递一个url或者一个本地的rpm包的路径
  • state:状态(present:默认的,表示安装,absent:表示删除,latest:安装为最新的版本)
# yum 安装http
ansible test -m yum -a 'name=httpd state=latest'
# yum 安装指定的nginx包
ansible test -m yum -a 'name=http://nginx.org/packages/centos/6/noarch/RPMS/nginx-release-centos-6-0.el6.ngx.noarch.rpm state=present'
# yum 安装包组
ansible test -m yum -a 'name="@Development tools" state=present'

yum_repository模块

用于管理yum源的,该模块包含如下选项:

  • name:第三方源的名称
  • baseurl:第三方源的URL地址
  • state:状态(present:默认的,表示添加,absent:表示删除)
# 添加第三方epel源
ansible test -m yum_repository -a "name=epel baseurl=https://download.fedoraproject.org/pub/epel/$releasever/$basearch/ "
# 删除第三方epel源
ansible test -m yum_repository -a "name=epel state=absent"

user模块

用于管理用户,添加、删除、修改用户,该模块包含如下选项:

  • home:指定用户的家目录,需要与creathome配合使用
  • groups:指定用户的属组
  • uid:指定用户的uid
  • password:指定用户的密码
  • name:指定用户名
  • creathome:是否创建家目录(yes|no)
  • system:当创建一个用户,设置这个用户是系统用户。这个设置不能更改现有用户
  • remove:当state=absent时,remove=yes 则表示连同家目录一起删除,等价于userdel -r
  • state:设置账号状态,不指定为创建,absent表示删除
  • shell:指定用户的shell环境
  • comment:对用户的描述信息
  • force:当state=absent时,等价于userdel --force
  • group:指定基本组
  • groups:指定附加组,如果指定为(‘groups=’)表示删除所有组
  • login_class:可以设置用户的登陆类 FreeBSD、OpenBSD、NetBSD系统
  • move_home:如果设置为`home='时, 试图将用户主目录移动到指定的目录
  • non_unique:该选项允许改变非唯一的用户ID值
  • update_password:更新用户密码
# 创建一个jack用户
ansible test -m user -a 'name="jack"'
# 删除一个jack用户
ansible test -m user -a 'name="jack" state=absents'
# 创建test用户,生成密钥时,只会生成公钥文件和私钥文件,和直接使用ssh-keygen指令效果相同,不会生成authorized_keys文件
ansible test -m user -a 'name=test generate_ssh_key=yes ssh_key_bits=2048 ssh_key_file=.ssh/id_rsa'

NOTE:指定password参数时,不能使用明文密码,因为密码会被直接传送到被管理主机的/etc/shadow文件中,所以需要先将密码字符串进行加密处理。然后将得到的字符串放到password中即可,具体如下:

echo "123456" | openssl passwd -1 -salt $(< /dev/urandom tr -dc '[:alnum:]' | head -c 32) -stdin
$1$4P4PlFuE$ur9ObJiT5iHNrb9QnjaIB0
#使用上面的密码创建用户
ansible all -m user -a 'name=foo password="$1$4P4PlFuE$ur9ObJiT5iHNrb9QnjaIB0"'

不同的发行版默认使用的加密方式可能会有区别,具体可以查看/etc/login.defs文件确认,centos 6.5版本使用的是SHA512加密算法

group模块

用于对组的管理,该模块包含如下选项:

  • gid:设置组的GID号
  • name:管理组的名称
  • state:指定组状态,默认为创建,设置值为absent为删除
  • system:设置值为yes,表示为创建系统组
# 创建一个mysql组,并添加mysql用户加入组中
ansible all -m group -a 'name=mysql gid=306 system=yes'
ansible all -m user -a 'name=mysql uid=306 system=yes group=mysql'

lineinfile模块

用于对文件里的内容处理,该模块包含如下选项:

  • path:必选项 指定要修改的配置文件
  • regexp:匹配要修改的内容
  • line:要增加或者修改的内容
  • state:对文件进行删除还是增加 present(表示增加,当匹配到时进行修改,当没有匹配到时在最后增加一行,默认为此项)|absent(表示删除,当匹配到时进行删除)
  • backrefs:
    no:表示如果没有匹配到,则增加line;如果匹配成功,则替换line;
    yes:表示如果没有匹配到,则不变line;如果匹配成功,则替换line;
  • backup:
    no:表示如果没有匹配到,则增加line;如果匹配成功,则替换line;不备份原文件
    yes:表示如果没有匹配到,则增加line;如果匹配成功,则替换line;备份原文件
  • insertafter:在匹配到的行之后添加一行(匹配的是此行)
  • insertbefore:在匹配到的行之前添加一行(匹配的是此行)
  • owner:修改文件属主的属性
  • group:修改文件属组的属性
  • mode:修改文件的权限
  • validate:在修改保存sudoers文件前,验证语法,如果有错,执行时,会报出来,并修改不成功
# 替换存在的行的内容
ansible oms -m lineinfile -a 'path=/etc/sudoers regexp="SYSTEM,SOFTWARE" line="STAPLES_ADMIN ALL=(ROOT) NOPASSWD:NETWORKING,LOCATE,STORAGE,DELEGATING,DRIVERS,SYSTEM,SOFTWARE,SERVICES,PROCESSES,FILE" backrefs=no'
# 匹配到的行后增加一行
ansible oms -m lineinfile -a 'dest=/etc/sudoers insertafter="Cmnd_Alias SYSTEM = /usr/sbin/reboot, /usr/sbin/halt, /usr/bin/ansible, /usr/bin/ssh" line="Cmnd_Alias FILE = /bin/mkdir,/bin/touch,/usr/bin/vim"'
# 删除匹配的行
ansible oms -m lineinfile -a 'path=/etc/sudoers state=absent regexp="PROCESSES,FILE"'
# 将sre开头的最后匹配的一行前边加上#,可以用()形式做替换变更,类似sed,\1表示第一个()里的内容,注意这个用法需要backrefs设置成yes,开启扩展正则匹配
ansible ctx-lf -m lineinfile -a "dest=/tmp/sudoers regexp=^(sre.*)$ line='#\1' backrefs=yes" -u sre -s -i hosts
# 加入validate的验证,比如sudo文件如果改错了,可能影响整个系统的管理,加入验证之后,如果修改的sudo文件格式错误,将不会保存
ansible ctx-lf -m lineinfile -a "dest=/tmp/sudoers regexp=^(sre.*)$ line='123123' validate='visudo -cf %s'" -u sre -s -i hosts

mount模块

用于配置挂载点,该模块包含如下选项:

  • fstype:必选项,挂载文件的类型
  • name:必选项,挂载点
  • opts:传递给mount命令的参数
  • src:必选项,要挂载的文件
  • state:必选项
    present:只处理fstab中的配置
    absent:删除挂载点
    mounted:自动创建挂载点并挂载之
    umounted:卸载
ansible test -m mount 'name=/mnt src=/dev/loop0 fstype=ext4 state=mounted opts=rw'

get_url模块

用于从http、ftp、https服务器上下载文件(类似于wget),该模块包含如下选项:

  • sha256sum:下载完成后进行sha256 check
  • timeout:下载超时时间,默认10s
  • url:下载的url
  • url_password、url_username:主要用于需要用户名密码进行验证的情况
  • use_proxy:使用代理,代理需事先在环境变更中定义
get_url: url=http://example.com/path/file.conf dest=/etc/foo.conf sha256sum=b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c

Ansible 通过playbook实现zabbix-agent批量部署

# 根据系统版本安装对应的zabbix-agent的客户端
tree ./install_zabbix_agtend/
./install_zabbix_agtend/
├── READ.MD
├── roles
│   ├── CentOS_6
│   │   ├── files
│   │   │   └── zabbix-agent-4.0.10-1.el6.x86_64.rpm
│   │   ├── handlers
│   │   │   └── main.yml
│   │   ├── meta
│   │   ├── tasks
│   │   │   └── main.yml
│   │   ├── templates
│   │   │   └── zabbix_agentd.conf.j2
│   │   └── vars
│   │       └── main.yml
│   └── CentOS_7
│       ├── files
│       │   └── zabbix-agent-4.0.10-1.el7.x86_64.rpm
│       ├── handlers
│       │   └── main.yml
│       ├── meta
│       ├── tasks
│       │   └── main.yml
│       ├── templates
│       │   └── zabbix_agentd.conf.j2
│       └── vars
│           └── main.yml
└── site.yml

15 directories, 12 files

# 根据不同的系统版本(CentOS 6|7)安装对应的zabbix-agent的客户端
cat site.yml
---
- hosts: "{{ hostsnames }}"
  become: yes
  become_method: su
  roles:
  - {role: CentOS_6, when: "ansible_distribution_major_version == '6'" }
  - {role: CentOS_7, when: "ansible_distribution_major_version == '7'" }

# 以CentOS7为例:
pwd
/data/ansible/install_zabbix_agtend/roles/CentOS_7

# 主配置文件
cat tasks/main.yml
- name: Create directory
  file: path=/data/soft state=directory
- name: Copy RPM package
  copy: dest=/data/soft src=zabbix-agent-4.0.10-1.el7.x86_64.rpm backup=yes
- name: Install Zabbix-agentd
  #shell: rpm -ivh /data/soft/zabbix-agent-3.4.11-1.el7.x86_64.rpm
  yum: name=/data/soft/zabbix-agent-4.0.10-1.el7.x86_64.rpm state=present
- name: Modify configuration file
  template: src=zabbix_agentd.conf.j2 dest=/etc/zabbix/zabbix_agentd.conf backup=yes
  tags:
  - Modify
  #notify: Restart zabbix_agentd
- name: Start Zabbix-Agentd
  service: name=zabbix-agent state=started enabled=yes

# 复制rpm包文件
tree /data/ansible/install_zabbix_agtend/roles/CentOS_7/files/
/data/ansible/install_zabbix_agtend/roles/CentOS_7/files/
└── zabbix-agent-4.0.10-1.el7.x86_64.rpm

0 directories, 1 file

# 设置变量配置文件
 cat vars/main.yml
#server_hostname: {{ ansible_hostname }}
#server_ip: {{ ansible_default_ipv4.address }}
#server_ip: {{ ansible_all_ipv4_addresses }}
ZabbixServerIP: 192.168.168.237
ZabbixHostMetadata: basic

# 设置zabbix_agtend的配置文件
egrep -v "^$|^#" templates/zabbix_agentd.conf.j2
PidFile=/var/run/zabbix/zabbix_agentd.pid
LogFile=/var/log/zabbix/zabbix_agentd.log
LogFileSize=0
Server={{ ZabbixServerIP }}
ServerActive={{ ZabbixServerIP }}
Hostname={{ agent_name }}_{{ ansible_default_ipv4.address }}
HostMetadataItem=system.uname
Include=/etc/zabbix/zabbix_agentd.d/*.conf

# 设置重启的触发条件
cat handlers/main.yml
- name: Restart zabbix_agentd
  service: name=zabbix-agent state=restarted
Linux下实现回制游戏的C代码需要考虑几个关键点。首先,需要定义游戏的角色及其属性。假设有两个角色A和B,可以定义结构体来表示它们的属性,如生命值、攻击力等。然后,需要定义游戏的回逻辑,比如角色A先攻击角色B,在每个回结束后,判断角色的生命值是否为零,若是,则游戏结束;否则,切换角色进行下一回。接着,可以编写主函数来实现具体的游戏逻辑。 以下是一个简单的回制游戏的C代码示例: ```c #include <stdio.h> // 定义角色结构体 typedef struct { int hp; // 生命值 int atk; // 攻击力 } Character; // 角色A攻击角色B void attack(Character* attacker, Character* defender) { defender->hp -= attacker->atk; printf("角色A攻击了角色B,角色B剩余生命值:%d\n", defender->hp); } int main() { Character A = {100, 10}; // 定义角色A Character B = {100, 5}; // 定义角色B int round = 1; // 初始化回数 while (A.hp > 0 && B.hp > 0) { printf("第%d回\n", round++); if (round % 2 == 1) { attack(&A, &B); // A先攻击B } else { attack(&B, &A); // B攻击A } } if (A.hp <= 0) { printf("游戏结束,角色B获胜!\n"); } else { printf("游戏结束,角色A获胜!\n"); } return 0; } ``` 以上代码通过结构体定义了两个角色A和B的属性,并在每个回中实现了角色之间的攻击。每个回结束后,会判断角色的生命值,如果有一个角色的生命值降至零以下,则游戏结束。最后,根据生命值判断输出获胜的角色。 这只是一个简单的示例,实际的回制游戏可能还涉及更复杂的逻辑和功能。可以根据需求进一步扩展和修改这段代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值