ansible安装及使用
一、ansible介绍
1、ansible简介
官方的title是“Ansible is Simple IT Automation”——简单的自动化IT工具。
Ansible跟其他IT自动化技术的区别在于其关注点并非配置管理、应用部署或IT流程工作流,而是提供一个统一的界面来协调所有的IT自动化功能,因此Ansible的系统更加易用,部署更快。
Ansible可以让用户避免编写脚本或代码来管理应用,同时还能搭建工作流实现IT任务的自动化执行。IT自动化可以降低技术门槛及对传统IT的依赖,从而加快项目的交付速度。
2、ansible优缺点
优点:
- 轻量级,他不需要去客户端安装agent,更新时,只需要在操作机上进行一次更新即可
- 批量任务执行可以写成脚本,而且不用分发到远程就可以执行
- 使用python编写的,维护更简单
- 支持sudo
缺点
- 对于几千台、上万台机器的操作,还不清楚性能、效率情况如何,需要进一步了解。
3、ansible架构及工作原理
andible基本架构如下图所示
ansible core : ansible 自身核心模块
host inventory: 主机库,定义可管控的主机列表
connection plugins: 连接插件,一般默认基于 ssh 协议连接
modules:core modules ( 自带模块 ) 、 custom modules ( 自定义模块 )
playbooks :剧本,按照所设定编排的顺序执行完成安排任务
Ansible工作原理如下图:
1、管理端支持local 、ssh、zeromq 三种方式连接被管理端,默认使用基于ssh的连接---这部分对应基本架构图中的连接模块;
2、可以按应用类型等方式进行Host Inventory(主机群)分类,管理节点通过各类模块实现相应的操作---单个模块,单条命令的批量执行,我们可以称之为 ad-hoc;
3、管理节点可以通过playbooks 实现多个task的集合实现一类功能,如web服务的安装部署、数据库服务器的批量备份等。playbooks我们可以简单的理解为,系 统通过组合多条ad-hoc操作的配置文件 。
Ansible默认是通过SSH通道来管理的,也就是它所说的免客户端方式管理, 它底层是通过 paramiko 来实现的。
ansible执行过程大体过程如下图,其中暖色调的代表已经模块化。
二、部署安装
名称 |
IP |
操作系统 |
用途 |
ansible-server |
192.168.95.10/24 |
CentOS7.1 |
管理端 |
client-1 |
192.168.95.11/24 |
CentOS7.1 |
|
client-2 |
192.168.95.12/24 |
CentOS7.1 |
|
1、ansible安装方式有、源码、pip、yum。
1.1 源码安装
源码安装需要python2.6以上版本,其依赖模块paramiko、PyYAML、Jinja2、httplib2、simplejson、pycrypto模块,以上模块可以通过pip或easy_install 进行安装
1.2pip安装
pip是专门用来管理Python模块的工具,Ansible会将每次正式发布都更新到pip仓库中。所以通过pip安装或更新Ansible,会比较稳妥的拿到最新稳定版。
1.3 yum安装
1)安装epel源
yum install http://mirrors.163.com/centos/7.4.1708/extras/x86_64/Packages/epel-release-7-9.noarch.rpm
2)查看epel源并安装ansible
[root@node2 ~]ll /etc/yum.repos.d/epel*
[root@node2 ~]yum install ansible -y
3)查看ansible版本
ansible --version
2 ansible组成介绍
tree /etc/ansible/
/etc/ansible/
├── ansible.cfg # ansible的配置文件
├── hosts # ansible的主仓库 用来存储需要管理的远程主机的相关信息
└── roles
3、ansible七个命令
ansible
常用参数:-m 模块
-i PATH, --inventory=PATH 指定库存主机文件的路径,默认为/etc/ansible/hosts.
-a (arguments) 命令行参数
示例:ansible test1 -m copy -a "src=/tmp/test.txt dest=/tmp/test.txt "
ansible-doc
//列出所有已安装的模块
# ansible-doc -l
//查看具体某模块的用法,这里如查看command模块
# ansible-doc -s command
absible-galaxy
ansible-galaxy 指令用于方便的从https://galaxy.ansible.com/ 站点下载第三方扩展模块,我们可以形象的理解其类似于centos下的yum、python下的pip或easy_install 。如下示例:
ansible-galaxy install aeriscloud.docker
ansible-link
ansible-lint是对playbook的语法进行检查的一个工具。用法是ansible-lint playbook.yml 。
ansible-playbook
该指令是使用最多的指令,其通过读取playbook 文件后,执行相应的动作。
ansible-pull
适用于以下场景:你有数量巨大的机器需要配置,即使使用非常高的线程还是要花费很多时间;你要在一个没有网络连接的机器上运行Anisble,比如在启动之后安装。
ansible-vault
注意:重点是ansible和ansible-playbook
4、主机组(在hosts文件内配置)
[hangzhou]
host1
host2
[jiaxing]
host3
host4
5、ansible默认配置文件
Ansible默认安装好后有一个配置文件/etc/ansible/ansible.cfg
ansible简单使用
[root@test ansible]# ansible test1 -m ping -k
SSH password:
192.168.147.101 | FAILED => Using a SSH password instead of a key is not possible because Host Key checking is enabled and sshpass does not support this. Please add this host's fingerprint to your known_hosts file to manage this host.
报错处理办法:
在ansible.cfg配置文件中,也会找到如下部分:
# uncomment this to disable SSH key host checking
host_key_checking = False
默认host_key_checking部分是注释的,通过找开该行的注释,同样也可以实现跳过 ssh 首次连接提示验证部分。
可见采用密码方式比较麻烦,实际应用中采用ssh 互信方式。
配置ssh 互信时,只需要管理主机能ssh被管理机器不需要输入密码即可。
三、ansible常用模块
3.1、ping
ansible test1 -m ping
3.2、setuop
setup模块,主要用于获取主机信息,在playbooks里经常会用到的一个参数gather_facts就与该模块相关。setup模块下经常使用的一个参数是filter参数,具体使用示例如下:
#查看主机内存信息
[root@test ~]# ansible test1 -m setup -a 'filter=ansible_*_mb'
#查看网卡信息
[root@test ~]# ansible test1 -m setup -a 'filter=ansible_eth0'
#将所有主机的信息输入到/tmp/facts目录下,每台主机的信息输入到主机名文件中(/etc/ansible/hosts里的主机名)
[root@test ~]# ansible all -m setup --tree /tmp/facts
3.3 file 模块
file模块主要用于远程主机上的文件操作。
(group、mode、owner):定义文件/目录
path:定义文件路径
recurse:递归的设置,只对目录有效。
src:要被链接的源文件路径,只应用于state=link的情况
dest:被连接的路径,只应用于state=link的情况
state:directory:如果目录不存在,创建目录
file:即使文件不存在,也不会创建
link:创建软连接
hard:创建硬链接
touch:文件不存在,则会创建。如果存在则会,则更新最后修改的时间。
absent:删除目录、文件或取消链接。
示例:
[root@test ~]# ansible test1 -m file -a "src=/etc/fstab dest=/tmp/fstab state=link"
[root@test ~]# ansible test1 -m file -a "path=/tmp/fstab state=absent"
[root@test ~]# ansible test1 -m file -a "path=/tmp/fstab state=touch"
3.4 cop模块
backup:在覆盖之前将原文件备份,备份文件包含时间信息。有两个选项:yes|no
content:用于替代"src",可以直接设定指定文件的值
directory_mode:递归的设定目录的权限,默认为系统默认权限
force:如果目标主机包含该文件,但内容不同,如果设置为yes,则强制覆盖,如果为no,则只有当目标主机的目标位置不存在该文件时,才复制。默认为yes
others:所有的file模块里的选项都可以在这里使用
src:要复制到远程主机的文件在本地的地址,可以是绝对路径,也可以是相对路径。如果路径是一个目录,它将递归复制。在这种情况下,如果路径使用"/"来结尾,则只复制目录里的内容,如果没有使用"/"来结尾,则包含目录在内的整个内容全部复制,类似于rsync。
示例:
[root@test ~]# ansible test1 -m copy -a "src=/tmp/test.txt dest=/tmp/test.txt owner=foo group=foo mode=0644"
3.5 command 模块
- creates:一个文件名,当该文件存在,则该命令不执行
- free_form:要执行的linux指令
- chdir:在执行指令之前,先切换到该指定的目录
- removes:一个文件名,当该文件不存在,则该选项不执行
- executable:切换shell来执行指令,该执行路径必须是一个绝对路径
注意:command模块不是调用的shell的指令,所以没有bash的环境变量,也不能使用shell的一些操作方式,其他和shell没有区别
示例:[root@test ansible]# ansible test1 -a 'df -h'
3.6 shell 模块
用法其本和command一样,不过的是其是通过/bin/sh进行执行,所以shell 模块可以执行任何命令,就像在本机执行一样。
示例:[root@test ansible]# ansible test1 -m shell -a 'ps -ef | grep sshd'
3.7 raw 模块
用法和shell 模块一样 ,其也可以执行任意命令,就像在本机执行一样
注:raw模块和comand、shell 模块不同的是其没有chdir、creates、removes参数,chdir参数的作用就是先切到chdir指定的目录后,再执行后面的命令,这在后面很多模块里都会有该参数 。
3.8 script 模块
将管理端的shell 在被管理主机上执行,其原理是先将shell 复制到远程主机,再在远程主机上执行,原理类似于raw模块。
3.9 service 模块
- arguments:给命令行提供一些选项
- enabled:是否开机启动 yes|no
- name:必选项,服务名称
- pattern:定义一个模式,如果通过status指令来查看服务的状态时,没有响应,就会通过ps指令在进程中根据该模式进行查找,如果匹配到,则认为该服务依然在运行
- runlevel:运行级别
- sleep:如果执行了restarted,在则stop和start之间沉睡几秒钟
- state:对当前服务执行启动,停止、重启、重新加载等操作(started,stopped,restarted,reloaded)
示例:[root@test ansible]# ansible test1 -m service -a "name=httpd state=started enabled=yes"
3.10 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:确认该任务计划是创建还是删除
- user:以哪个用户的身份执行
示例:[root@test ansible]# ansible test1 -m cron -a 'name="check dirs" hour="5,2" job="ls -alh >/dev/null"'
3.11 filesystem 模块
- dev:目标块设备
- force:在一个已有文件系统的设备上强制创建
- fstype:文件系统的类型
- opts:传递给mkfs命令的选项
3.12 yum 模块
- config_file:yum的配置文件
- disable_gpg_check:关闭gpg_check
- disablerepo:不启用某个源
- enablerepo:启用某个源
- name:要进行操作的软件包的名字,也可以传递一个url或者一个本地的rpm包的路径
- state:状态(present,absent,latest)
示例:[root@test ansible]# ansible test1 -m yum -a 'name=httpd state=latest'
3.13 user和group 模块
user模块是请求的是useradd, userdel, usermod三个指令,goup模块请求的是groupadd, groupdel, groupmod 三个指令。
示例:
创建用户:[root@test ~]# ansible test1 -m user -a 'createhome=yes home=/home/user1 password=123456 name=user1 shell=/bin/bash state=present'
删除用户:[root@test ~]# ansible test1 -m user -a 'remove=yes name=user1 state=absent'
3.14 synchronize 模块
使用rsync同步文件
- archive: 归档,相当于同时开启recursive(递归)、links、perms、times、owner、group、-D选项都为yes ,默认该项为开启
- checksum: 跳过检测sum值,默认关闭
- compress:是否开启压缩
- copy_links:复制链接文件,默认为no ,注意后面还有一个links参数
- delete: 删除不存在的文件,默认no
- dest:目录路径
- dest_port:默认目录主机上的端口 ,默认是22,走的ssh协议
- dirs:传速目录不进行递归,默认为no,即进行目录递归
- rsync_opts:rsync参数部分
- set_remote_user:主要用于/etc/ansible/hosts中定义或默认使用的用户与rsync使用的用户不同的情况
- mode: push或pull 模块,push模的话,一般用于从本机向远程主机上传文件,pull 模式用于从远程主机上取文件
示例:[root@test ansible]# ansible test1 -m synchronize -a 'src=/tmp/helloworld dest=/var/www'
3.15 mount 模块
- dump
- fstype:必选项,挂载文件的类型
- name:必选项,挂载点
- opts:传递给mount命令的参数
- src:必选项,要挂载的文件
- state:必选项
- present:只处理fstab中的配置
- absent:删除挂载点
- mounted:自动创建挂载点并挂载之
- umounted:卸载
示例:
#创建设备
[root@test ansible]# ansible test1 -a 'dd if=/dev/zero of=/disk.img bs=4k count=1024'
#与/dev/loop1关联
[root@test ansible]# ansible test1 -a 'losetup /dev/loop1 /disk.img'
#格式化
[root@test ansible]# ansible test1 -m filesystem -a 'fstype=ext3 force=yes opts=-F
#挂载
[root@test ansible]# ansible test1 -m mount -a 'name=/mnt src=/dev/loop1 fstype=ext3 state=mounted opts=rw'
四、ansible-playbook
4.1 playbook 构成
- Target section: 定义将要执行 playbook 的远程主机组
- Variable section: 定义 playbook 运行时需要使用的变量
- Task section: 定义将要在远程主机上执行的任务列表
- Handler section: 定义 task 执行完成以后需要调用的任务
一般所需的目录层有:(视情况可变化)
- vars 变量层
- tasks 任务层
- handlers 触发条件
- files 文件
- template 模板
4.2.1host和user
playbook中的每一个play的目的都是为了让某个或某些主机以某个指定的用户身份执行任务。
hosts 用于指定要执行指定任务的主机其可以是一个或多个由冒号分隔主机组。
user 执行该任务组的用户
remote_user 则用于指定远程主机上的执行任务的用户,与user相同。
sudo 如果设置为yes,执行该任务组的用户在执行任务时,获取root权限。
4.2.2 任务列表和action
play的主体部分是task list
示例:
tasks:
- name: make sure apache is running
service: name=httpd state=running
4.2.3 handlers
在notify中列出的操作称为handler也即notify中调用 handler中定义的操作。
注意:在 notify 中定义内容一定要和tasks中定义的 - name 内容一样,这样才能达到触发的效果,否则会不生效。
4.2.4 tags
ansible中可以对play、role、include、task打一个tag(标签),然后:
- 当命令ansible-playbook有-t参数时,只会执行-t指定的tag
- 当命令ansible-playbook有--skip-tags参数时,则除了--skip-tags指定的tag外,执行其他所有
4.2.5 var
#变量定义在文件中
[root@test playbooks]# cat variables
port: 80
http: nginx
五、playbook常用模板
template
template模块和copy类似,不同在于template会做变量替换。
常用参数:
backup:如果原目标文件存在,则先备份目标文件
dest:目标文件路径
force:是否强制覆盖,默认为yes
group:目标文件属组
mode:目标文件的权限
owner:目标文件属主
src:源模板文件路径
validate:在复制之前通过命令验证目标文件,如果验证通过则复制
示例:
- template: src=/mytemplates/foo.j2 dest=/etc/file.conf owner=bin group=wheel mode=0644
- template: src=/mytemplates/foo.j2 dest=/etc/file.conf owner=bin group=wheel mode="u=rw,g=r,o=r"
set_face
set_fact模块可以让你在远程受管机器上去执行脚本的过程来计算我们需要的值,这些值可以被用在模板或者变量中。这些值有点类似setup模块中的参数,只不过setup模块是以单台主机为单位的。
示例:
tasks:
-name: Calculate InnoDB buffer pool size
set facl: innodb_buffer_pool_size_mb=”{{ ansible_mentotal_mb /2 }}”
pause
暂停模块可以让我们在playbooks中暂停一段时间,可以知道一个时间段,或者提示用户继续。在命令行中没生么有,但在playbook中,很有用处。
示例:
# Pause for 5 minutes to build app cache.
- pause: minutes=5
# Pause until you can verify updates to an application were successful.
- pause:
# A helpful reminder of what to look out for post-update.
- pause: prompt="Make sure org.foo.FooOverload exception is not present"
wait_for
wait_for模块用来检测一个tcp端口是否准备好接收远程连接,这是由远程主机来完成的。
示例:
# 10秒后在当前主机开始检查8000端口,直到端口启动后返回
- wait_for: port=8000 delay=10
# 检查path=/tmp/foo直到文件存在后继续
- wait_for: path=/tmp/foo
# 直到/var/lock/file.lock移除后继续
- wait_for: path=/var/lock/file.lock state=absent
-name: Wait for Tomcat to start
wait_for: port=8080 state=started
assemble
assemble组装模块把多个受管主机的文件合并成一个文件,当配置文件不允许包含的时候,非常有用。特别在设置root用户的authorized_keys文件的时候。
示例:
# Example from Ansible Playbooks
- assemble: src=/etc/someapp/fragments dest=/etc/someapp/someapp.conf
# When a delimiter is specified, it will be inserted in between each fragment
- assemble: src=/etc/someapp/fragments dest=/etc/someapp/someapp.conf delimiter='### START FRAGMENT ###'
add_host
add_host添加主机模块是playbook中一个强大的模块,它可以让你动态的添加受管主机到一个play中。
示例:
# add host to group 'just_created' with variable foo=42
- add_host: name={{ ip_from_ec2 }} groups=just_created foo=42
group_by
group_by模块可以让我们根据主机的真实特性进行分组,真实特性可以通过add_fact来实现。Group_by模块只接受一个参数,key,同样组名的机器被分到一个组里面。
示例:
# Create groups based on the machine architecture
- group_by: key=machine_{{ ansible_machine }}
# Create groups like 'kvm-host'
- group_by: key=virt_{{ ansible_virtualization_type }}_{{ ansible_virtualization_role }}
get_url
该模块主要用于从http、ftp、https服务器上下载文件(类似于wget),主要有如下选项:
sha256sum:下载完成后进行sha256 check;
timeout:下载超时时间,默认10s
url:下载的URL
url_password、url_username:主要用于需要用户名密码进行验证的情况
use_proxy:是事使用代理,代理需事先在环境变更中定义
示例:
- name: download foo.conf
get_url: url=http://example.com/path/file.conf dest=/etc/foo.conf mode=0440
- name: download file with sha256 check
get_url: url=http://example.com/path/file.conf dest=/etc/foo.conf sha256sum=b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c
debug
调试模块,用于在调试中输出信息
常用参数:
msg:调试输出的消息
var:将某个任务执行的输出作为变量传递给debug模块,debug会直接将其打印输出
verbosity:debug的级别(默认是0级,全部显示)
fail
用于终止当前playbook的执行,通常与条件语句组合使用,当满足条件时,终止当前play的运行。可以直接由failed_when取代。
选项只有一个:
msg:终止前打印出信息
示例:
- fail: msg="The system may not be provisioned according to the CMDB status."
when: cmdb_status != "to-be-staged"
六、playbook的roles和include
include
1、包含task文件
---
# possibly saved as tasks/foo.yml
- name: placeholder foo
command: /bin/foo
- name: placeholder bar
command: /bin/bar
2、包含handle文件
---
# this might be in a file like handlers/handlers.yml
- name: restart apache
service: name=apache state=restarted
在play末尾包含上面的handler文件:
handlers:
- include: handlers/handlers.yml
3、直接包含playbook文件
roles(角色)
roles用来组织playbook结构,以多层目录和文件将playbook更好的组织在一起
角色允许你将变量、文件、任务、模板、handlers放到一个文件夹中,然后包含它们。在建立好一个有效的依赖关系之后,还可以在一个角色中包含另外一个角色。
roles组织的playbook结构:
site.yml
webservers.yml
fooservers.yml
roles/
common/ #下面的子目录都不是必须提供的,没有的目录会自动忽略,不会出现问题,所以你可以只有tasks/子目录也没问题
files/
templates/
tasks/
handlers/
vars/
meta/
webservers/
然后在playbook文件中包含common和webservers这两个role:
---
- hosts: user_group1
roles:
- common
- webservers
ansible安装及使用的更多相关文章
- 初探ansible安装
一.ansible介绍常用的自动化运维工具 Puppet —基于 Ruby 开发,采用 C/S 架构,扩展性强,基于 SSL,远程命令执行相对较弱SaltStack —基于 Python 开发,采用 ...
- Ansible安装配置Nginx
一.思路 现在一台机器上编译安装好nginx.打包,然后在用ansible去下发 cd /etc/ansible 进入ansible配置文件目录 mkdir roles/{common,install ...
- Ansible安装配置及使用
一.Ansible特点 1.不需要安装客户端,通过sshd通信 2.基于模块工作,模块可以由任何序言开发 3.不仅支持命令行使用模块,也支持编写yaml格式的playbook 4.支持sudo 5.有 ...
- Ansible安装配置
Ansible工具的安装与配置 Ansible基于SSH,不需要在远程端安装任何软件,只需要在管理端安装ansible及其组件即可. Ansible使用前提是已配置ssh密钥免登陆. 一.安装组件: ...
- ansible安装二进制kubernetes-1.14.1
主机信息: 主机IP 主机名 角色 10.10.3.181 k8s-m1 kube-apiserver,kube-controller-manager,kube-scheduler,etcd 10. ...
- Ansible安装部署以及常用模块详解
一. Ansible 介绍Ansible是一个配置管理系统configuration management system, python 语言是运维人员必须会的语言, ansible 是一个基于py ...
- 内网环境使用ansible安装software 需要外网时,如何绑定代理呢
内网环境使用ansible安装software 需要外网时,如何绑定代理呢? 方法一: 在ansible 的脚本里,yum install 的地方,添加语句: environment: https_p ...
- Ansible 安装与配置(一)
公司大概有200多云主机需要进行管理,但是如果通过手工管理费时还累最终结果也容易出错,所以考虑通过自动化的方式来管理云主机,目前开源的自动化工具,大家用的比较多的有Ansible和Saltstack这 ...
- Ansible安装及OS规划
Ansible安装 1.以管理用户mtnsadmin连接服务器后下载安装包(-O表示将下载的文件存放到指定的文件夹下,同时重命名下载的文件) sudo wget -O /etc/yum.re ...
- 【mac】ansible安装及基础使用
安装 环境释放 mac 10.12.5 #more /System/Library/CoreServices/SystemVersion.plist 安装命令 #ruby -e "$(cur ...
随机推荐
- linux2.6内核netfilter架构分析
1.2.6内核的netfilter与2.4的有很大不同: ChangeLog-2.6.15 中有下面这样的描述: commit 9fb9cbb1082d6b31fb45aa1a14432449a0df ...
- libubox-uloop
参考:libubox组件(3)——uloop uloop是提供事件驱动机制接口,类似libevent事件框架,基于epoll接口来实现的. uloop三大功能:事件管理(uloop_fd).超时管理( ...
- 目录视图摘要视图订阅 基于Extjs开发不允许为空的文本框提示及相应的验证错误提示(转)
原文地址:http://blog.csdn.net/kunoy/article/details/8007585 本文主要解决问题: 1.区分哪些文本框不允许为空,很多网站都采用在文本框后加*号,ext ...
- quick-cocos2d-x 创建自定义lua绑定c++类
内容主要参考 “在quick-cocos2d-x中添加自定义的类给lua使用” ( http://www.codeo4.cn/archives/746) 1. quick-coco2d-x 使用 to ...
- 一步一步安装Git控件版本工具
Git是一款免费.开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目.Git的读音为/gɪt/.Git是一个开源的分布式版本控制系统,用以有效.高速的处理从很小到非常大的项目版本管理.[2 ...
- (转)java synchronised关键字
转自:http://www.cnblogs.com/mengdd/archive/2013/02/16/2913806.html Java 多线程(六) synchronized关键字详解 Java ...
- 进度条在.net导入Excel时的应用实例
这篇文章主要介绍了进度条在.net导入Excel时的应用,以实例形式讲述了.net导入Excel时根据页面情况显示进度条的实现方法,非常具有实用价值,需要的朋友可以参考下 本文实例讲述了进度条在.ne ...
- 提高PHP编程技术的方法
提高PHP编程技术的方法 下面介绍的是提高PHP编程技术的几种方法. 1.PHP标签 我知道有些人写PHP代码的时候喜欢用缩略标签<? ?>,但是这可不是个好习惯,因为缩略标签在有些服务器 ...
- 报错 findMergedAnnotation activemq
springmvc 集成activemq引入activemq-all-5.14.4有冲突 springmvc 4.2.9集成activemq-5.14.4时报错,错误信息如下 NoSuchMethod ...
- 【BZOJ1509】[NOI2003]逃学的小孩 直径
[BZOJ1509][NOI2003]逃学的小孩 Description Input 第一行是两个整数N(3 N 200000)和M,分别表示居住点总数和街道总数.以下M行,每行给出一条街道的 ...