• linux09 /消息队列、saltstack工具


    linux09 /消息队列、saltstack工具

    1. 消息队列之rabbitmq

    • 消息队列概述

      消息被发送到队列中。“消息队列”是在消息的传输过程中保存消息的容器。消息队列管理器在将消息从它的源中继到它的目标时充当中间人。队列的主要目的是提供路由并保证消 
      息的传递;如果发送消息时接收者不可用,消息队列会保留消息,直到可以成功地传递它。
      
    • rabbitmq安装/启动/创建后台管理用户

      1.安装rabbitmq,配置好阿里云的yum源,epel源
        yum -y install erlang  rabbitmq-server
      
      2.启动rabbitmq服务端
        systemctl start rabbitmq-server
      
      3.开启rabbitmq的管理后台页面
        rabbitmq-plugins enable rabbitmq_management
      
      4.重启rabbitmq服务端
        systemctl restart rabbitmq-server
      
      5.创建rabbitmq的后台管理用户
        sudo rabbitmqctl add_user zhangsan zhangsan123   # 创建用户 
        sudo rabbitmqctl set_user_tags zhangsan  administrator  # 设置用户管理员身份
        sudo rabbitmqctl set_permissions -p "/" zhangsan ".*" ".*" ".*"    # 允许zhangsan用户,对所有的队列都可以读写
      
      6.重启服务端,让用户添加生效
        systemctl restart rabbitmq-server
      
    • 安装pika模块

      pip3 install pika==0.11.1
      
    • 通过python的pika模块,实现生产消费者

      1、生产者代码如下:

      vim pro.py   # 创建生产者文件
      python3 pro.py   # 执行生产者文件,将消息放到消息队列中
      
      #!/usr/bin/env python
      import pika
      
      # 创建凭证,使用rabbitmq用户密码登录
      credentials = pika.PlainCredentials("zhangsan","zhangsan123")
      
      # 新建连接,这里localhost可以更换为服务器ip
      connection = pika.BlockingConnection(pika.ConnectionParameters('192.168.16.192',credentials=credentials))
      
      # 创建频道
      channel = connection.channel()
      
      # 声明一个队列,用于接收消息,队列名字叫“西游记”
      channel.queue_declare(queue='西游记')
      # 将消息放到消息队列中
      channel.basic_publish(exchange='',
                            routing_key='西游记',
                            body='大师兄,师傅被妖怪抓走了')
      print("已经发送了消息")
      connection.close()
      
      # 注意:
      # 1.程序退出前确保刷新网络缓冲以及消息发送给rabbitmq,需要关闭本次连接
      # 2.在rabbitmq中,消息想要发送给队列,必须经过交换(exchange),初学可以使用空字符串交换(exchange=''),允许精确的指定发送给哪个队列(routing_key=''),参数body值发送的数据
      

      2、消费者代码如下:

      vim con.py   # 创建消费者文件
      python3 con.py   # 执行消费者文件,将消息从消息队列中取走
      
      import pika
      # 建立与rabbitmq的连接,前四行都是连接到同一个rabbitmq服务端以及同一个队列
      credentials = pika.PlainCredentials("zhangsan","zhangsan123")
      connection = pika.BlockingConnection(pika.ConnectionParameters('192.168.16.192',credentials=credentials))
      channel = connection.channel()
      channel.queue_declare(queue="西游记")
      
      
      def callbak(ch,method,properties,body):
          print("消费者取出了消息:%r"%body.decode("utf8"))
      # 有消息来临,立即执行callbak,没有消息则夯住,等待消息,必须指定队列名称
      channel.basic_consume(callbak,queue="西游记",no_ack=True)  # no_ack 不用确认 
      # 开始消费,接收消息
      channel.start_consuming()
      
    • 消息之ack机制

      1、生产者代码如下:

      #!/usr/bin/env python
      import pika
      # 创建凭证,使用rabbitmq用户密码登录
      credentials = pika.PlainCredentials("zhangsan","zhangsan123")
      
      # 新建连接,这里localhost可以更换为服务器ip
      connection = pika.BlockingConnection(pika.ConnectionParameters('192.168.16.192',credentials=credentials))
      
      # 创建频道
      channel = connection.channel()
      
      # 新建一个hello队列,用于接收消息
      channel.queue_declare(queue='hello')
      
      # 在消息队列中添加消息
      channel.basic_publish(exchange='',
                            routing_key='hello',
                            body='hello world')
      print("已经发送了消息")
      connection.close()
      

      2、消费者代码如下:

      import pika
      
      credentials = pika.PlainCredentials("zhangsan","zhangsan123")
      connection = pika.BlockingConnection(pika.ConnectionParameters('192.168.16.192',credentials=credentials))
      channel = connection.channel()
      
      # 声明一个队列(创建一个队列)
      channel.queue_declare(queue='hello')
      
      def callback(ch, method, properties, body):
          print("消费者接受到了任务: %r" % body.decode("utf-8"))
          # int('abc')  测试
          # 回复方式:告诉rabbitmq服务端,已经取走了消息
          ch.basic_ack(delivery_tag=method.delivery_tag)
          
      # 关闭no_ack,代表给与服务端ack回复,确认给与回复
      channel.basic_consume(callback,queue='hello',no_ack=False)  # no_ack=False 使用确认机制,代表确认消息成功接收并处理
      channel.start_consuming()
      
      # 如果没有设置no_ack=False,int('abc'):测试如果在这里报错,消息队列中的消息也会显示被取走
      
    • 消息持久化

      import pika
      # 无密码
      # connection = pika.BlockingConnection(pika.ConnectionParameters('123.206.16.61'))
      
      # 有密码
      credentials = pika.PlainCredentials("zhangsan","zhangsan123")
      connection = pika.BlockingConnection(pika.ConnectionParameters('192.168.16.192',credentials=credentials))
      channel = connection.channel()
      # 声明一个队列(创建一个队列)
      # 默认此队列不支持持久化,如果服务挂掉,数据丢失
      # durable=True 开启持久化,必须新开启一个队列,原本的队列已经不支持持久化了
      '''
      实现rabbitmq持久化条件
       delivery_mode=2
      使用durable=True声明queue是持久化
       
      '''
      channel.queue_declare(queue='hello',durable=True)  # 此步表示队列是支持持久化的参数
      channel.basic_publish(exchange='',
                            routing_key='hello', # 消息队列名称
                            body='hello world',
                            # 支持数据持久化
                            properties=pika.BasicProperties(
                                delivery_mode=2,#代表消息是持久的  2
                            )
                            )
      connection.close()
      

    2. 云计算

    • 概念:

      狭义的云计算是指IT基础设施的交付和使用模式,指通过网络以按需、易扩展的方式获得所需的资源(硬件、平台、软件)。提供资源的网络被称为“云”。“云”中的资源在使用者看来是可以无限扩展的,并且可以随时获取,按需使用,随时扩展,按使用付费。这种特性经常被称为像水电一样使用IT基础设施。广义的云计算是指服务的交付和使用模式,指通过网络以按需、易扩展的方式获得所需的服务。这种服务可以是IT和软件、互联网相关的,也可以是任意其他的服务。
      

    3. 远程过程调用的实现:rpc

    • rpc概述:

      RPC是远程过程调用(Remote Procedure Call)的缩写形式。SAP系统RPC调用的原理其实很简单,有一些类似于三层构架的C/S系统,第三方的客户程序通过接口调用SAP内部的标准或自定义函数,获得函数返回的数据进行处理后显示或打印
      
    • 服务端示例代码:

      from xmlrpc.server import SimpleXMLRPCServer
      
      # 调用函数
      def respon_string(str):
          return "我得到了字符串:%s"%str
      
      if __name__ == '__main__':
          server = SimpleXMLRPCServer(('localhost', 8888)) # 初始化
          server.register_function(respon_string, "get_string") # 注册函数
          print ("Listening for Client")
          server.serve_forever()  # 保持等待调用状态
      
    • 客户端示例代码:

      from xmlrpc.client import ServerProxy
      
      if __name__ == '__main__':
          server = ServerProxy("http://localhost:8888") # 初始化服务器
          print (server.get_string("hello")) # 调用函数并传参
      

    4. saltstack运维工具学习

    • 环境准备

      # 两台服务器
      192.168.16.85   master
      192.168.16.105  minion1
      
      # 修改两台机器的主机名,用于主机名通信,加速salt的命令执行 
      hostnamectl set-hostname  master 
      hostnamectl set-hostname  minion  
      
      # 关闭两台机器的iptables防火墙策略,防止端口拒绝
      iptables -F  # 清空防火墙规则
      systemctl stop firewalld  # 关闭防火强服务
      systemctl disable firewalld  # 禁止防火墙开机自启 
      
      # 分别安装两个软件,下载前配置好阿里的yum源
      yum install salt-master -y 
      yum install salt-minion -y 
      
    • 配置/etc/hosts文件,用于主机名通信

      192.168.16.105 minion
      192.168.16.85  master
      
    • 修改salt的master和minion的配置文件

      # 在master机器上修改/etc/salt/master文件改为如下
      [root@master ~]# grep -vE "^$|#" /etc/salt/master 
      interface: 0.0.0.0
      publish_port: 4505
      user: root
      worker_threads: 5
      ret_port: 4506
      
      # 修改minion的配置如下
      [root@minion yum.repos.d]# grep -vE "^$|#" /etc/salt/minion 
      master: master
      master_port: 4506
      user: root
      id: minion1
      
    • 分别启动salt-master和salt-minion

      [root@master ~]# systemctl start salt-master
      [root@minion ~]# systemctl start salt-minion
      
    • 查看密钥是否被读取到了

      在master上输入salt-key -L ,查看是否读取到了minion的信息
      
    • 分别检查两台机器的密钥信息,是否一致

      在master机器上输入 salt-key -f minion1
      在minion机器上输入 salt-call --local key.finger
      
    • 接收minion1的密钥,准备管理他了

      [root@master ~]# salt-key -a  minion1
      
    • 对于密钥管理的命令如下

      salt-key  参数如下
      -L  # 查看KEY状态
      -A  # 允许所有
      -D  # 删除所有
      -a  # 认证指定的key
      -d  # 删除指定的key
      -r  # 注销掉指定key(该状态为未被认证)
      
      salt-key -d  密钥名  # 删除密钥 
      
    • 使用salt的第一个命令,测试服务器是否存活

      salt '*'  test.ping   # 发送命令接口,ping一下被管理的机器,是否存货,返回true活着,负责挂掉了,或者salt-minion服务器宕机了
      salt 是核心管理命令
      "*"  目标匹配 
      test.ping  是test模块下的一个功能函数 
      
    • salt的命令接口

      salt 'minion1'  test.fib 50   # 输出50以内的斐波那契数列
      salt '*'  cmd.run 'touch /tmp/first'  --summary   # 输出salt命令执行结果的详细情况
      
    • 远程安装nginx,以及启动nginx

      salt '*'  cmd.run  "systemctl status nginx"
      salt 'minion1'  cmd.run  "yum install nginx -y"
      salt '*'  cmd.run  "systemctl status nginx"
      salt '*'  cmd.run  "netstat -tunlp|grep 80"
      salt '*'  cmd.run  "yum install  net-tools -y"
      salt '*'  cmd.run  "netstat -tunlp|grep 80"
      salt '*'  cmd.run  "systemctl start nginx"
      salt '*'  cmd.run  "netstat -tunlp|grep 80"
      salt '*'  cmd.run  "systemctl stop nginx"
      
    • salt提供的软件安装模块,其实页是在远程调用yum命令而已

      salt '*' pkg.install "nginx"  # 在minion上安装nginx
      salt '*' pkg.remove "nginx"   # 卸载minion上的nginx
      salt '*' pkg.version "nginx"  # 检查pkg包的版本
      
    • salt提供的服务信息模块其实调用的是 systemctl 命令

      [root@master ~]# salt '*' service.start "redis"
      minion1:
          True
      [root@master ~]# salt '*' service.status "redis"
      minion1:
          True
      
    • 输出json格式的数据,以及yaml格式的数据

      [root@master ~]# salt '*' service.status "redis" --out=json
      {
          "minion1": false
      }
      
      [root@master ~]# salt '*' service.start "redis" --out=json
      {
          "minion1": true
      }
      
    • salt采集服务器静态信息之grains模块,其实就是用python写的一个超大的字典

      salt '*' grains.items
      
      salt '*' grains.item fqdn_ip4 --out=json  # 取出所有管理服务器的ip地址,并转换成json格式
      

    5. Python API调用SaltStack

    • python API介绍

      /usr/bin/salt默认使用的接口是LocalClient,该接口只能在salt master上使用
      [root@master  ~]$python
      Python 2.7.5 (default, Jul 13 2018, 13:06:57)
      [GCC 4.8.5 20150623 (Red Hat 4.8.5-28)] on linux2
      Type "help", "copyright", "credits" or "license" for more information.
      >>> import salt.client
      >>> local = salt.client.LocalClient()  #<salt.client.LocalClient object at 0x7f886dbdd850>
      
      # 检查minion服务器信息:相当于linux中直接执行命令
      >>> local.cmd('*','test.fib',[10])
      >>> local.cmd('*','cmd.run',['hostname'])#向所有minion发送命令
      {'slave': 'slave'}
      >>> local.cmd('*','cmd.run',['ifconfig'])
      >>> local.cmd('*','cmd.run',['crontab -l'])
      >>> local.cmd('*','cmd.run',['df -h'])
      
      # 启停minion的服务:相当于linux中执行systemctl
      >>> local.cmd('*','service.stop',['nginx'])
      {'slave': True}
      >>> local.cmd('*','service.status',['nginx'])
      {'slave': False}
      >>> local.cmd('*','service.start',['nginx'])
      {'slave': True}
      

    5. yaml语法

    • 语法规则、支持的数据结构

      1.语法规则
          大小写敏感
          使用缩进表示层级关系   
          缩进时禁止tab键,只能空格
          缩进的空格数不重要,相同层级的元素左侧对其即可
          # 表示注释行
      2.yaml支持的数据结构
          对象: 键值对,也称作映射 mapping 哈希hashes 字典 dict    冒号表示 key: value   key冒号后必须有一个空格
          数组: 一组按次序排列的值,又称为序列sequence 列表list     短横线  - list1
          纯量: 单个不可再分的值
      
    • 示例:

      用python的数据结构做对比
      {"软件班":
      	{"学生":
      		{"男同学":["张三","李四"],"女同学":["张小三","张小四"]}
      	}
      }
      
      
      用yaml表示这个数据结构,在线yaml网站http://www.bejson.com/validators/yaml_editor/  
      "软件班": 
         "学生": 
            "男同学":
                 - "张三"
                 - "李四"
            "女同学": 
              - "张小三"
              - "张小四"
      
  • 相关阅读:
    循序渐进Python3(十一) --4--  web之jQuery
    循序渐进Python3(十一) --3--  web之dom
    循序渐进Python3(十一) --2-- web之javascript
    web之css伪类
    循序渐进Python3(十一) --1-- web之css
    循序渐进Python3(十一) --0-- web之html
    循序渐进Python3(十)-- 1 -- pymysql
    循序渐进Python3(十)-- 2 -- SqlAlchemy
    循序渐进Python3(十)-- 3 -- SqlAlchemy
    循序渐进Python3(十)-- 4 -- paramiko
  • 原文地址:https://www.cnblogs.com/liubing8/p/12110956.html
Copyright © 2020-2023  润新知