Ansible 安装与配置

本章主要讲的是 Ansible 安装与基本配置,主要包含以下内容:

  1. Ansible 环境准备
  2. 安装 Ansible
  3. 配置运行环境
  4. Ansible实践

Ansible 环境准备

从 GitHub 获取 Ansible,准备控制主机,查看被管节点。

使用的操作系统为 Centos 7.0,自带 Python 2.7.5。

角色 主机名 IP 地址 组名 CPU Web 根目录
被管节点 web1 192.168.46.128 webservers 2 /website
被管节点 web2 192.168.46.129 webservers 2 /website
控制节点 ansiblecontrol 192.168.46.130 --- --- ---

永久性的修改主机名称hostnamectl set-hostname web1

安装 Ansible

Ansible 的安装方式分为直接用源码安装以及用包管理工具安装。

直接用源码安装

从 GitHub 源码库安装方式

提取 Ansible 源代码

  1. git clone https://github.com/ansible/ansible.git -- recursive
  2. cd ./ansible
  3. # 减少告警/错误信息输出,可在安装时加上 -q 参数
  4. source ./hacking/env-setup -q

若没有安装 pip,安装对应 Python 版本的 pip

  1. sudo easy_install pip

安装 Ansible 控制主机需要的 Python 模块

  1. sudo pip install paramiko PyYAML Jinja2 httplib2 six

当更新 Ansible 版本时,要更新 git 源码树以及 git 中指向 Ansible 自身的模块(称为 submodules)

  1. git pull --rebase
  2. git submodule update --init --recursive

运行 env-setup 脚本(默认资源清单 inventory 文件是 /etc/ansible/hosts)

  1. .. code-block:: bash
  2. echo "127.0.0.1" > ~/ansible_hosts
  3. export ANSIBLE_HOSTS=~/ansible_hosts

通过 GitHub 仓库安装的,需要把仓库中 examples 目录下的 ansible.cfg 复制到 /etc/ansible 目录下

用包管理工具安装

pip安装方式

  1. #安装 pip
  2. sudo easy_install pip
  3. #通过 pip 命令安装 Ansible
  4. sudo pip install ansible

通过 pip 安装的,没有自动生成的配置文件,需要自己新建 /etc/ansible/ansible.cfg

配置运行环境

配置文件优先级:

  1. ANSIBLE_CONFIG:首先,Ansible 命令会检查环境变量,以及环境变量指向的配置文件。
  2. ./ansible.cfg:其次,会检查当前目录下的 ansible.cfg 配置文件。
  3. ~/ansible.cfg:再次,会检查当前用户 home 目录下的 ansible.cfg 配置文件。
  4. /etc/ansible/ansible.cfg:最后,会检查安装时自动生成的配置文件。

配置 Ansible 环境

  1. 使用环境变量方式配置
  2. 设置 ansible.cfg 配置参数
  1. [defaults]
  2. #inventory = /etc/ansible/hosts #inventory文件路径
  3. #library = /usr/share/my_modules/ #模块文件路径
  4. #module_utils = /usr/share/my_module_utils/ #自定义模块工具存放目录
  5. #remote_tmp = ~/.ansible/tmp #临时文件远程主机存放目录
  6. #local_tmp = ~/.ansible/tmp #临时文件本地存放目录
  7. #plugin_filters_cfg = /etc/ansible/plugin_filters.yml
  8. #forks = 5 #默认开启的进程数
  9. #poll_interval = 15 #默认轮询时间间隔
  10. #sudo_user = root #默认sudo用户
  11. #ask_sudo_pass = True #是否需要sudo密码
  12. #ask_pass = True #是否需要密码
  13. #transport = smart 通信机制,如果本地系统支持 ControlPersist技术的话,将会使用(基于OpenSSH)‘ssh’,如果不支持将使用‘paramiko’,其他传输选项‘local’,‘chroot’,’jail’等等
  14. #remote_port = 22 #连接被管节点的管理端口
  15. #module_lang = C #模块运行的语言环境
  16. #module_set_locale = False
  17. #gathering = implicit #facts信息收集开关,implicit(默认不收集)
  18. #gather_subset = all #facts 的收集范围
  19. # gather_timeout = 10 #收集超时间隔
  20. # Ansible facts are available inside the ansible_facts.* dictionary
  21. # namespace. This setting maintains the behaviour which was the default prior
  22. # to 2.5, duplicating these variables into the main namespace, each with a
  23. # prefix of 'ansible_'.
  24. # This variable is set to True by default for backwards compatibility. It
  25. # will be changed to a default of 'False' in a future release.
  26. # ansible_facts.
  27. # inject_facts_as_vars = True
  28. #roles_path = /etc/ansible/roles #role存放路径
  29. #host_key_checking = False #是否检查SSH主机的密钥
  30. # change the default callback, you can only have one 'stdout' type enabled at a time.
  31. #stdout_callback = skippy
  32. # enable callback plugins, they can output to stdout but cannot be 'stdout' type.
  33. #callback_whitelist = timer, mail
  34. # Determine whether includes in tasks and handlers are "static" by
  35. # default. As of 2.0, includes are dynamic by default. Setting these
  36. # values to True will make includes behave more like they did in the
  37. # 1.x versions.
  38. #task_includes_static = False
  39. #handler_includes_static = False
  40. # Controls if a missing handler for a notification event is an error or a warning
  41. #error_on_missing_handler = True
  42. #sudo_exe = sudo #ansible sudo执行命令
  43. #sudo_flags = -H -S -n #ansible sudo执行参数
  44. #timeout = 10 #ansible SSH连接的超时间隔/秒
  45. #remote_user = root #ansible 远程认证用户
  46. #log_path = /var/log/ansible.log #指定存储日志的文件
  47. #module_name = command #ansible 默认执行模块
  48. #executable = /bin/sh #ansible 命令执行 shell
  49. # if inventory variables overlap, does the higher precedence one win
  50. # or are hash values merged together? The default is 'replace' but
  51. # this can also be set to 'merge'.
  52. #hash_behaviour = replace #ansible 主机变量重复处理方式
  53. # by default, variables from roles will be visible in the global variable
  54. # scope. To prevent this, the following option can be enabled, and only
  55. # tasks and handlers within the role will see the variables there
  56. #private_role_vars = yes
  57. #jinja2_extensions = jinja2.ext.do,jinja2.ext.i18n #Jinja2 扩展列表
  58. #private_key_file = /path/to/file #ansible ssh 私钥文件
  59. # If set, configures the path to the Vault password file as an alternative to
  60. # specifying --vault-password-file on the command line.
  61. #vault_password_file = /path/to/vault_password_file
  62. #ansible_managed = Ansible managed: {file} modified on %Y-%m-%d %H:%M:%S by {uid} on {host} #在 jinja2 中格式化 ansible_managed 变量
  63. #ansible_managed = Ansible managed
  64. #display_skipped_hosts = True #开启显示跳过的主机
  65. # by default, if a task in a playbook does not include a name: field then
  66. # ansible-playbook will construct a header that includes the task's action but
  67. # not the task's args. This is a security feature because ansible cannot know
  68. # if the *module* considers an argument to be no_log at the time that the
  69. # header is printed. If your environment doesn't have a problem securing
  70. # stdout from ansible-playbook (or you have manually specified no_log in your
  71. # playbook on all of the tasks where you have secret information) then you can
  72. # safely set this to True to get more informative messages.
  73. #display_args_to_stdout = False
  74. #error_on_undefined_vars = False #开启错误,或者没有定义的变量
  75. #system_warnings = True #开启第三方包系统警告
  76. #deprecation_warnings = True #配置是否显示弃用警告
  77. # (as of 1.8), Ansible can optionally warn when usage of the shell and
  78. # command module appear to be simplified by using a default Ansible module
  79. # instead. These warnings can be silenced by adjusting the following
  80. # setting or adding warn=yes or warn=no to the end of the command line
  81. # parameter string. This will for example suggest using the git module
  82. # instead of shelling out to the git command.
  83. # command_warnings = False
  84. # set plugin path directories here, separate with colons
  85. #action_plugins = /usr/share/ansible/plugins/action #ansible action 插件路径
  86. #become_plugins = /usr/share/ansible/plugins/become
  87. #cache_plugins = /usr/share/ansible/plugins/cache
  88. #callback_plugins = /usr/share/ansible/plugins/callback
  89. #connection_plugins = /usr/share/ansible/plugins/connection
  90. #lookup_plugins = /usr/share/ansible/plugins/lookup
  91. #inventory_plugins = /usr/share/ansible/plugins/inventory
  92. #vars_plugins = /usr/share/ansible/plugins/vars
  93. #filter_plugins = /usr/share/ansible/plugins/filter
  94. #test_plugins = /usr/share/ansible/plugins/test
  95. #terminal_plugins = /usr/share/ansible/plugins/terminal
  96. #strategy_plugins = /usr/share/ansible/plugins/strategy
  97. # by default, ansible will use the 'linear' strategy but you may want to try
  98. # another one
  99. #strategy = free
  100. #bin_ansible_callbacks = False #开启 ansible 命令加载 callback 插件
  101. #nocows = 1 #是否开启 ansiblenocows 图形
  102. # set which cowsay stencil you'd like to use by default. When set to 'random',
  103. # a random stencil will be selected for each task. The selection will be filtered
  104. # against the `cow_whitelist` option below.
  105. #cow_selection = default
  106. #cow_selection = random
  107. # when using the 'random' option for cowsay, stencils will be restricted to this list.
  108. # it should be formatted as a comma-separated list with no spaces between names.
  109. # NOTE: line continuations here are for formatting purposes only, as the INI parser
  110. # in python does not support them.
  111. #cow_whitelist=bud-frogs,bunny,cheese,daemon,default,dragon,elephant-in-snake,elephant,eyes,\
  112. # hellokitty,kitty,luke-koala,meow,milk,moofasa,moose,ren,sheep,small,stegosaurus,\
  113. # stimpy,supermilker,three-eyes,turkey,turtle,tux,udder,vader-koala,vader,www
  114. #nocolor = 1 #是否开启 ansible 颜色输出
  115. # if set to a persistent type (not 'memory', for example 'redis') fact values
  116. # from previous runs in Ansible will be stored. This may be useful when
  117. # wanting to use, for example, IP information from one group of servers
  118. # without having to talk to them in the same playbook run to get their
  119. # current IP information.
  120. #fact_caching = memory
  121. #This option tells Ansible where to cache facts. The value is plugin dependent.
  122. #For the jsonfile plugin, it should be a path to a local directory.
  123. #For the redis plugin, the value is a host:port:database triplet: fact_caching_connection = localhost:6379:0
  124. #fact_caching_connection=/tmp
  125. # retry files
  126. # When a playbook fails a .retry file can be created that will be placed in ~/
  127. # You can enable this feature by setting retry_files_enabled to True
  128. # and you can change the location of the files by setting retry_files_save_path
  129. #retry_files_enabled = False
  130. #retry_files_save_path = ~/.ansible-retry
  131. # squash actions
  132. # Ansible can optimise actions that call modules with list parameters
  133. # when looping. Instead of calling the module once per with_ item, the
  134. # module is called once with all items at once. Currently this only works
  135. # under limited circumstances, and only with parameters named 'name'.
  136. #squash_actions = apk,apt,dnf,homebrew,pacman,pkgng,yum,zypper
  137. # prevents logging of task data, off by default
  138. #no_log = False
  139. # prevents logging of tasks, but only on the targets, data is still logged on the master/controller
  140. #no_target_syslog = False
  141. # controls whether Ansible will raise an error or warning if a task has no
  142. # choice but to create world readable temporary files to execute a module on
  143. # the remote machine. This option is False by default for security. Users may
  144. # turn this on to have behaviour more like Ansible prior to 2.1.x. See
  145. # https://docs.ansible.com/ansible/become.html#becoming-an-unprivileged-user
  146. # for more secure ways to fix this than enabling this option.
  147. #allow_world_readable_tmpfiles = False
  148. # controls the compression level of variables sent to
  149. # worker processes. At the default of 0, no compression
  150. # is used. This value must be an integer from 0 to 9.
  151. #var_compression_level = 9
  152. # controls what compression method is used for new-style ansible modules when
  153. # they are sent to the remote system. The compression types depend on having
  154. # support compiled into both the controller's python and the client's python.
  155. # The names should match with the python Zipfile compression types:
  156. # * ZIP_STORED (no compression. available everywhere)
  157. # * ZIP_DEFLATED (uses zlib, the default)
  158. # These values may be set per host via the ansible_module_compression inventory
  159. # variable
  160. #module_compression = 'ZIP_DEFLATED'
  161. #max_diff_size = 1048576 #diff文件的大小限制/字节
  162. # This controls how ansible handles multiple --tags and --skip-tags arguments
  163. # on the CLI. If this is True then multiple arguments are merged together. If
  164. # it is False, then the last specified argument is used and the others are ignored.
  165. # This option will be removed in 2.8.
  166. #merge_multiple_cli_flags = True
  167. # Controls showing custom stats at the end, off by default
  168. #show_custom_stats = True
  169. # Controls which files to ignore when using a directory as inventory with
  170. # possibly multiple sources (both static and dynamic)
  171. #inventory_ignore_extensions = ~, .orig, .bak, .ini, .cfg, .retry, .pyc, .pyo
  172. # This family of modules use an alternative execution path optimized for network appliances
  173. # only update this setting if you know how this works, otherwise it can break module execution
  174. #network_group_modules=eos, nxos, ios, iosxr, junos, vyos
  175. # When enabled, this option allows lookups (via variables like {{lookup('foo')}} or when used as
  176. # a loop with `with_foo`) to return data that is not marked "unsafe". This means the data may contain
  177. # jinja2 templating language which will be run through the templating engine.
  178. # ENABLING THIS COULD BE A SECURITY RISK
  179. #allow_unsafe_lookups = False
  180. # set default errors for all plays
  181. #any_errors_fatal = False
  182. [inventory]
  183. # enable inventory plugins, default: 'host_list', 'script', 'auto', 'yaml', 'ini', 'toml'
  184. #enable_plugins = host_list, virtualbox, yaml, constructed
  185. # ignore these extensions when parsing a directory as inventory source
  186. #ignore_extensions = .pyc, .pyo, .swp, .bak, ~, .rpm, .md, .txt, ~, .orig, .ini, .cfg, .retry
  187. # ignore files matching these patterns when parsing a directory as inventory source
  188. #ignore_patterns=
  189. # If 'true' unparsed inventory sources become fatal errors, they are warnings otherwise.
  190. #unparsed_is_failed=False
  191. [privilege_escalation]
  192. #become=True #是否开启 become 模式
  193. #become_method=sudo #定义 become 方式
  194. #become_user=root #定义 become 用户
  195. #become_ask_pass=False #是否定义 become 提示密码
  196. [paramiko_connection]
  197. #record_host_keys=False #是否记录主机 key
  198. #pty=False #是否开启命令执行伪终端
  199. # paramiko will default to looking for SSH keys initially when trying to
  200. # authenticate to remote devices. This is a problem for some network devices
  201. # that close the connection after a key failure. Uncomment this line to
  202. # disable the Paramiko look for keys function
  203. #look_for_keys = False
  204. # When using persistent connections with Paramiko, the connection runs in a
  205. # background process. If the host doesn't already have a valid SSH key, by
  206. # default Ansible will prompt to add the host key. This will cause connections
  207. # running in background processes to fail. Uncomment this line to have
  208. # Paramiko automatically add host keys.
  209. #host_key_auto_add = True
  210. [ssh_connection]
  211. #SSH 连接配置
  212. #ssh_args = -C -o ControlMaster=auto -o ControlPersist=60s #ansib ssh参数,ControlMaster用于设置是否启用 SSH的Multiplexing,关闭则写no,ControlPersist为SSH session保持的时间
  213. # control_path_dir = /tmp/.ansible/cp #ansible ssh 长连接控制文件
  214. #control_path_dir = ~/.ansible/cp
  215. # The path to use for the ControlPath sockets. This defaults to a hashed string of the hostname,
  216. # port and username (empty string in the config). The hash mitigates a common problem users
  217. # found with long hostnames and the conventional %(directory)s/ansible-ssh-%%h-%%p-%%r format.
  218. # In those cases, a "too long for Unix domain socket" ssh error would occur.
  219. #
  220. # Example:
  221. # control_path = %(directory)s/%%h-%%r
  222. #control_path =
  223. #pipelining = False #是否开启 pipelining 模式
  224. #scp_if_ssh = smart #是否开启scp模式推送脚本,smart(先尝试sftp推送,再尝试scp推送)
  225. # Control the mechanism for transferring files (new)
  226. # If set, this will override the scp_if_ssh option
  227. # * sftp = use sftp to transfer files
  228. # * scp = use scp to transfer files
  229. # * piped = use 'dd' over SSH to transfer files
  230. # * smart = try sftp, scp, and piped, in that order [default]
  231. #transfer_method = smart
  232. # if False, sftp will not use batch mode to transfer files. This may cause some
  233. # types of file transfer failures impossible to catch however, and should
  234. # only be disabled if your sftp version has problems with batch mode
  235. #sftp_batch_mode = False
  236. # The -tt argument is passed to ssh when pipelining is not enabled because sudo
  237. # requires a tty by default.
  238. #usetty = True
  239. #retries = 3 #重试与主机SSH连接的次数
  240. [persistent_connection]
  241. #持久连接配置
  242. #connect_timeout = 30 #持久连接超时间隔
  243. # The command timeout value defines the amount of time to wait for a command
  244. # or RPC call before timing out. The value for the command timeout must
  245. # be less than the value of the persistent connection idle timeout (connect_timeout)
  246. # The default value is 30 second.
  247. #command_timeout = 30
  248. [accelerate]
  249. #accelerate_port = 5099 #accelerate 远程监听端口
  250. #accelerate_timeout = 30 #accelerate 模式,命令执行超时时间/秒
  251. #accelerate_connect_timeout = 5.0 #accelerate 模式,连接超时时间/秒
  252. # The daemon timeout is measured in minutes. This time is measured
  253. # from the last activity to the accelerate daemon.
  254. #accelerate_daemon_timeout = 30
  255. # If set to yes, accelerate_multi_key will allow multiple
  256. # private keys to be uploaded to it, though each user must
  257. # have access to the system via SSH to add a new key. The default
  258. # is "no".
  259. #accelerate_multi_key = yes
  260. [selinux]
  261. #上下文配置
  262. #special_context_filesystems=nfs,vboxsf,fuse,ramfs,9p,vfat
  263. #libvirt_lxc_noseclabel = yes
  264. [colors]
  265. #highlight = white
  266. #verbose = blue
  267. #warn = bright purple
  268. #error = red
  269. #debug = dark gray
  270. #deprecate = purple
  271. #skip = cyan
  272. #unreachable = red
  273. #ok = green
  274. #changed = yellow
  275. #diff_add = green
  276. #diff_remove = red
  277. #diff_lines = cyan
  278. [diff]
  279. # always = no #是否一直打印diff
  280. # context = 3 #diff中显示的上下文行数

配置 Linux 主机 SSH 无密码访问

为避免 Ansible 下发指令时需要输入目标主机密码,通过证书签名达到 SSH 无密码访问。使用 ssh-keygen 和 ssh-copy-id 来实现快速证书的生成及公钥的下发。

在控制主机上创建密钥,执行ssh-keygen -t rsa,将在 /root/.ssh/ 下生成密钥,其中 id_rsa 为私钥, id_rsa.pub 为公钥。

  1. #生成密钥
  2. ssh-keygen -t rsa

下发密钥就是控制主机将公钥 is_rsa.pub 下发到被管节点上用户下的 .ssh 目录,并重命名为 authorized_keys,且权限值为400。

  1. #下发公钥到 web1(192.168.46.128)
  2. ssh-copy-id -i id_rsa root@192.168.46.128
  3. #ssh连接验证
  4. ssh root@192.168.46.128
  5. #退出
  6. exit

Ansible 实践

主机连通性测试

修改主机与组配置 /etc/ansible/hosts ,添加两台主机的ip地址,同时定义一个 webservers 组包含这两个地址

  1. 192.168.46.128
  2. 192.168.46.129
  3. [webservers]
  4. 192.168.46.128
  5. 192.168.46.129

用 ping 模块对单台主机进行 ping 操作

ansible 192.168.46.128 -m ping

结果如下

  1. 192.168.46.128 | SUCCESS => {
  2. "ansible_facts": {
  3. "discovered_interpreter_python": "/usr/bin/python"
  4. },
  5. "changed": false,
  6. "ping": "pong"
  7. }

对 webservers 组进行 ping 操作

ansible webservers -m ping

在命令后加 -v 或 -vvv 可得到详细的输出结果

结果如下

  1. 192.168.46.128 | SUCCESS => {
  2. "ansible_facts": {
  3. "discovered_interpreter_python": "/usr/bin/python"
  4. },
  5. "changed": false,
  6. "ping": "pong"
  7. }
  8. 192.168.46.129 | SUCCESS => {
  9. "ansible_facts": {
  10. "discovered_interpreter_python": "/usr/bin/python"
  11. },
  12. "changed": false,
  13. "ping": "pong"
  14. }

在被管节点上批量执行命令

在 home 目录下创建资源清单文件 inventory.cfg

vim inventory.cfg

内容如下:

  1. [webservers]
  2. 192.168.46.128
  3. 192.168.46.129

用 Ansible 的 shell 模块 在 webservers 组的服务器上显示 hello ansible(用 common 模块也可以实现)

ansible webservers -m shell -a '/bin/echo hello ansible' -i inventory.cfg

结果如下:

  1. 192.168.46.128 | CHANGED | rc=0 >>
  2. hello ansible
  3. 192.168.46.129 | CHANGED | rc=0 >>
  4. hello ansible

Ansible 获取帮助信息

ansible-doc -h 获得帮助

ansible-doc -l 获得工具下可使用的模块

ansible-doc -s 获得工具下模块支持的动作

总结

通过在 CentOS 上以不同的方式安装 Ansible 以及对 Ansible 进行参数配置,并通过 Ansible 在被管节点上执行命令。

《Ansible自动化运维:技术与佳实践》第二章读书笔记的更多相关文章

  1. 《深入理解JVM》第二章读书笔记

    Java内存区域与内存溢出异常 运行时数据区域 JVM执行java程序的时候有一个运行时数据区,每个区域有自己的作用,了解这些区域有助于我们理解JVM.JVM运行时数据区如图所示: 程序计数器 该区域 ...

  2. 《深入理解JVM虚拟机》读书笔记

    前言:<深入理解JVM虚拟机>是JAVA的经典著作之一,因为内容更偏向底层,所以之前一直没有好好的阅读过.最近因为刚好有空,又有了新目标.所以打算和<构架师的12项修炼>一起看 ...

  3. 20135320赵瀚青LINUX第二章读书笔记

    第二章-从内核出发 获取内核代码 使用git 获取最新提交到版本树的一个副本 $ git clone git://git.kernel.org/pub/scm/linux/kernel/git/tor ...

  4. Android深度探索--HAL与驱动开发----第二章读书笔记

    1. 底层开发工具包括: JDk6或者以上版本:Eclipse3.4或以上版本:ADT(用于开发Android应用程序),CDT(用于开发AndroidNDK程序):Android SDK:Andro ...

  5. Linux第二章读书笔记

    1.获取内核源码 1.1Git 分布式的:下载和管理Linux内核源代码: - 获取最新提交到版本树的一个副本 $ git clone git://git.kernel.org/pub/scm/lin ...

  6. 2013337朱荟潼 Linux第二章读书笔记——从内核出发

    1.获取内核源码 1.1Git 分布式的:下载和管理Linux内核源代码: - 获取最新提交到版本树的一个副本 $ git clone git://git.kernel.org/pub/scm/lin ...

  7. <深入理解计算机系统>第七章读书笔记

    第七章读书笔记 链接 链接:将各种代码和数据部分收集起来并组合成为一个单一文件的过程.(这个文件可被加载或拷贝到存储器并执行) 链接可以执行于编译,加载或运行时. 静态链接: 两个主要任务: 1 符号 ...

  8. Linux内核分析第四章 读书笔记

    Linux内核分析第四章 读书笔记 第一部分--进程调度 进程调度:操作系统规定下的进程选取模式 面临问题:多任务选择问题 多任务操作系统就是能同时并发地交互执行多个进程的操作系统,在单处理器机器上这 ...

  9. 《构建之法》第四&十七章读书笔记

     <构建之法>第四&十七章读书笔记 一.         前言 再次阅读<构建之法>,愈发被其中生动有趣的举例吸引.作为一本给予软件工程学生的书籍,其不以枯燥的理论知识 ...

随机推荐

  1. 对数变换(一些基本的灰度变换函数)基本原理及Python实现

    1. 基本原理 变换形式如下 $$T(r) = c\lg(r+1)$$ c为常数 由于对数函数的导数随自变量的增大而减小,对数变换将输入窄范围的低灰度值扩展为范围宽的灰度值和宽范围的高灰度值压缩为映射 ...

  2. 佳木斯集训Day2

    D2好点了,最起码不像之前那么水 T1按照常规操作是个找规律,类似于括号匹配的题,但是又不是,推进栈里,然后看最长的左括号有多少个,然后直接cout就可以了 #include <bits/std ...

  3. American daily English notes (enlarged edition): A review

    Life English is the most pragmatic kind of English when one wants to associate with foreigner friend ...

  4. Go中的日志及第三方日志包logrus

    有别的语言使用基础的同学工作中都会接触到日志的使用,Go中自然也有log相关的实现.Go log模块主要提供了3类接口,分别是 "Print .Panic .Fatal ",对每一 ...

  5. Springmvc的运行原理 SpringMvc的优点

    SpringMVC框架运行原理 1:客户端发送请求到前端控制器(DispatcherServlet),前端控制器根据请求信息(url),查询一个或多个HandlerMapping, 前端控制器,来决定 ...

  6. MVC+EF Core 完整教程20--tag helper详解

    之前我们有一篇:“动态生成多级菜单”,对使用Html Helper做了详细讲述,并且自定义了一个菜单的 Html Helper: https://www.cnblogs.com/miro/p/5541 ...

  7. Win服务程序编写以及安装一般步骤

    Win服务程序编写以及安装一般步骤 Windows服务的优点有:1. 能够自动运行.2. 不要求用户交互.3. 在后台运行.本文将介绍常见服务程序编写的一般步骤以及注意事项. 设计服务程序实例: 创建 ...

  8. AQS源码解析(一)-AtomicBoolean源码解析

    基本类: AtomicInteger AtomicLong AtomicBoolean 数组类型: AtomicIntegerArray AtomicLongArray AtomicReference ...

  9. EOS源码分析:transaction的一生

    最近在处理智能合约的事务上链问题,发现其中仍旧有知识盲点.原有的认识是一个事务请求会从客户端设备打包签名,然后通过RPC传到非出块节点,广播给超级节点,校验打包到可逆区块,共识确认最后变为不可逆区块. ...

  10. LoRaWAN_stack移植笔记(三)__SPI

    stm32相关的配置 由于例程使用的主控芯片为STM32L151C8T6,而在本设计中使用的主控芯片为STM32L051C8T6,内核不一样,并且Cube库相关的函数接口及配置也会有不同,所以芯片的驱 ...