最近机房刚上了一批机器(有100台左右),需要使用Nagios对这一批机器进行监控。领导要求两天时间完成所有主机的监控。从原来的经验来看,两天时间肯定完成不了。那怎么办?按照之前的想法,肯定是在nagios配置文件逐一添加每台客户端的监控信息,工作量巨大。突然,想到一个想法,是否可以通过脚本来实现批量对主机进行监控,也就是运维自动化。

写脚本,最重要的就是思路。思路压倒一切,经过思考最终决定就这么做了。先贴出来一张网路拓扑图:

整个过程可以分为三部分。

  • cmdb端:主要用来实现对数据的收集,采用两个API,一个是提供给客户机的API。用于将客户端的数据上传的cmdb服务器;另外一个API是nagios通过此API可以得到要监控主机的信息,然后对该信息进行整理,做成nagios监控模板。

  • Client端:通过Python脚本收集本机器要监控的软硬件信息,然后通过cmdb端提供的API接口将数据上传到cmdb端的数据库。

  • Nagios端:通过cmdb端提供的API接口实现对cmdb收集到的信息进行抓取,然后将数据写入到模板,最后copy到naigos指定的objects目录,最终实现对客户机的监控。

这三部分最重要的应该是CMDB端。接下来通过安装django和编写API接口实现cmdb可以正常工作。可以将cmdb端分为三个步骤来完成:

  • 安装django

  • 配置django

  • 编写API接口

首先来进行安装django:

在安装django之前首先应该安装python(版本建议2.7.)

  1. 1.下载django软件包
  2. 可以到django官方网站下载最新django软件包(https://www.djangoproject.com).
  3. 2.解压缩并安装软件包
  4. tar -zxvf Django-1.5.1.tar.gz
  5. cd Django-1.5.1
  6. python setup.py install

创建项目和应用:

  1. 1.创建一个项目
  2. python startproject simplecmdb
  3. 2.创建一个应用
  4. python startapp hostinfo

配置django:

1.修改setting.py

  • DATABASES = {'ENGIN':'django.db.backends.sqlite','name':path.join('CMDB.db')}  #使用的数据库及数据库名

  • INSTALLED_APPS =(hostinfoINSTALLED_APPS = ('hostinfo')

  • INSTALLED_APPS = ('hostinfo')    #应用的名称

2.修改urls.py

  • url(r'^api/gethost\.json$','hostinfo.views.gethosts'),   #nagios客户端访问API接口地址

  • url(r'^api/clooect$','hostinfo.views.collect'),   #客户端访问API进行上传数据的API

  • url(r'^admin/',include(admin.site.urls)),   #django后台管理登入url

  • from django.contrib import admin

  • admin.autodiscover()

3.修改项目hostinfo下的views.py

代码如下:

  1. # Create your views here.
  2. #包含以下模块
  3. from django.shortcuts import render_to_response
  4. from django.http import HttpResponse
  5. from models import Host, HostGroup
  6. #包含json模块
  7. try:
  8. import json
  9. except ImportError,e:
  10. import simplejson as json
  11. #用来接收客户端服务器发送过来的数据
  12. def collect(request):
  13. req = request
  14. if req.POST:
  15. vendor = req.POST.get('Product_Name')
  16. sn = req.POST.get('Serial_Number')
  17. product = req.POST.get('Manufacturer')
  18. cpu_model = req.POST.get('Model_Name')
  19. cpu_num = req.POST.get('Cpu_Cores')
  20. cpu_vendor = req.POST.get('Vendor_Id')
  21. memory_part_number = req.POST.get('Part_Number')
  22. memory_manufacturer = req.POST.get('Manufacturer')
  23. memory_size = req.POST.get('Size')
  24. device_model = req.POST.get('Device_Model')
  25. device_version = req.POST.get('Firmware_Version')
  26. device_sn = req.POST.get('Serial_Number')
  27. device_size = req.POST.get('User_Capacity')
  28. osver = req.POST.get('os_version')
  29. hostname = req.POST.get('os_name')
  30. os_release = req.POST.get('os_release')
  31. ipaddrs = req.POST.get('Ipaddr')
  32. mac = req.POST.get('Device')
  33. link = req.POST.get('Link')
  34. mask = req.POST.get('Mask')
  35. device = req.POST.get('Device')
  36. host = Host()
  37. host.hostname = hostname
  38. host.product = product
  39. host.cpu_num = cpu_num
  40. host.cpu_model = cpu_model
  41. host.cpu_vendor = cpu_vendor
  42. host.memory_part_number = memory_part_number
  43. host.memory_manufacturer = memory_manufacturer
  44. host.memory_size = memory_size
  45. host.device_model = device_model
  46. host.device_version = device_version
  47. host.device_sn = device_sn
  48. host.device_size = device_size
  49. host.osver = osver
  50. host.os_release = os_release
  51. host.vendor = vendor
  52. host.sn = sn
  53. host.ipaddr = ipaddrs
  54. host.save() #将客户端传过来的数据通过POST接收,存入数据库
  55.  
  56. return HttpResponse('OK') #如果插入成功,返回'ok'
  57. else:
  58. return HttpResponse('no post data')
  59. #提供给NAGIOS 的API
  60. def gethosts(req):
  61. d = []
  62. hostgroups = HostGroup.objects.all()
  63. for hg in hostgroups:
  64. ret_hg = {'hostgroup':hg.name,'members':[]}
  65. members = hg.members.all()
  66. for h in members:
  67. ret_h = {'hostname':h.hostname, #API接口返回的数据
  68. 'ipaddr':h.ipaddr
  69. }
  70. ret_hg['members'].append(ret_h)
  71. d.append(ret_hg)
  72. ret = {'status':0,'data':d,'message':'ok'}
  73. return HttpResponse(json.dumps(ret))

4.修改model.py 文件

代码如下:

  1. from django.db import models
  2. # Create your models here.
  3. #插入数据库的Host表,主要存储客户端主机的信息
  4. class Host(models.Model):
  5. """store host information"""
  6. vendor = models.CharField(max_length=30,null=True)
  7. sn = models.CharField(max_length=30,null=True)
  8. product = models.CharField(max_length=30,null=True)
  9. cpu_model = models.CharField(max_length=50,null=True)
  10. cpu_num = models.CharField(max_length=2,null=True)
  11. cpu_vendor = models.CharField(max_length=30,null=True)
  12. memory_part_number = models.CharField(max_length=30,null=True)
  13. memory_manufacturer = models.CharField(max_length=30,null=True)
  14. memory_size = models.CharField(max_length=20,null=True)
  15. device_model = models.CharField(max_length=30,null=True)
  16. device_version = models.CharField(max_length=30,null=True)
  17. device_sn = models.CharField(max_length=30,null=True)
  18. device_size = models.CharField(max_length=30,null=True)
  19. osver = models.CharField(max_length=30,null=True)
  20. hostname = models.CharField(max_length=30,null=True)
  21. os_release = models.CharField(max_length=30,null=True)
  22. ipaddr = models.IPAddressField(max_length=15)
  23. def __unicode__(self):
  24. return self.hostname
  25. #主机组表,用来对主机进行分组
  26. class HostGroup(models.Model):
  27. name = models.CharField(max_length=30)
  28. members = models.ManyToManyField(Host)

5.修改admin.py文件

  1. #from models import Host, IPaddr
  2. from models import Host, HostGroup
  3. from django.contrib import admin
  4. #设置在django在admin后天显示的名称
  5. class HostAdmin(admin.ModelAdmin):
  6. list_display = ['vendor',
  7. 'sn',
  8. 'product',
  9. 'cpu_model',
  10. 'cpu_num',
  11. 'cpu_vendor',
  12. 'memory_part_number',
  13. 'memory_manufacturer',
  14. 'memory_size',
  15. 'device_model',
  16. 'device_version',
  17. 'device_sn',
  18. 'device_size',
  19. 'osver',
  20. 'hostname',
  21. 'os_release'
  22. ]
  23. #在django后台amdin显示的组名称
  24. class HostGroupAdmin(admin.ModelAdmin):
  25. list_display = ['name',]
  26. #将如上两个类的数据展示到django的后台
  27. admin.site.register(HostGroup,HostGroupAdmin)
  28. admin.site.register(Host, HostAdmin)

6.创建数据库

python manager.py syncdb  #创建数据库

7.启动应用

python manager.py runserver 0.0.0.0:8000

8.测试

http://132.96.77.12:8000/admin

通过上图可以看到,django已经配置成功。

接下来可以在客户端编写收集主机信息的脚本了,主要抓取cpu、内存、硬盘、服务器型号、服务器sn、ip地址、主机名称、操作系统版本等信息,共7个脚本:

1.cpu抓取脚本:

  1. #!/usr/local/src/python/bin/python
  2. #-*- coding:utf-8 -*-
  3. from subprocess import PIPE,Popen
  4. import re
  5. def getCpuInfo():
  6. p = Popen(['cat','/proc/cpuinfo'],shell=False,stdout=PIPE)
  7. stdout, stderr = p.communicate()
  8. return stdout.strip()
  9. def parserCpuInfo(cpudata):
  10. pd = {}
  11. model_name = re.compile(r'.*model name\s+:\s(.*)')
  12. vendor_id = re.compile(r'vendor_id\s+:(.*)')
  13. cpu_cores = re.compile(r'cpu cores\s+:\s([\d]+)')
  14. lines = [line for line in cpudata.split('\n')]
  15. for line in lines:
  16. model = re.match(model_name,line)
  17. vendor = re.match(vendor_id,line)
  18. cores = re.match(cpu_cores,line)
  19. if model:
  20. pd['Model_Name'] = model.groups()[0].strip()
  21. if vendor:
  22. pd['Vendor_Id'] = vendor.groups()[0].strip()
  23. if cores:
  24. pd['Cpu_Cores'] = cores.groups()[0]
  25. else:
  26. pd['Cpu_Cores'] = int('1')
  27. return pd
  28. if __name__ == '__main__':
  29. cpudata = getCpuInfo()
  30. print parserCpuInfo(cpudata)

2.硬盘抓取脚本:

  1. #!/usr/local/src/python/bin/python
  2. #-*- coding:utf-8 -*-
  3. from subprocess import PIPE,Popen
  4. import re
  5. def getDiskInfo():
  6. disk_dev = re.compile(r'Disk\s/dev/[a-z]{3}')
  7. disk_name = re.compile(r'/dev/[a-z]{3}')
  8. p = Popen(['fdisk','-l'],shell=False,stdout=PIPE)
  9. stdout, stderr = p.communicate()
  10. for i in stdout.split('\n'):
  11. disk = re.match(disk_dev,i)
  12. if disk:
  13. dk = re.search(disk_name,disk.group()).group()
  14. n = Popen('smartctl -i %s' % dk,shell=True,stdout=PIPE)
  15. stdout, stderr = n.communicate()
  16. return stdout.strip()
  17. def parserDiskInfo(diskdata):
  18. ld = []
  19. pd = {}
  20. device_model = re.compile(r'(Device Model):(\s+.*)')
  21. serial_number = re.compile(r'(Serial Number):(\s+[\d\w]{1,30})')
  22. firmware_version = re.compile(r'(Firmware Version):(\s+[\w]{1,20})')
  23. user_capacity = re.compile(r'(User Capacity):(\s+[\d\w, ]{1,50})')
  24. for line in diskdata.split('\n'):
  25. serial = re.search(serial_number,line)
  26. device = re.search(device_model,line)
  27. firmware = re.search(firmware_version,line)
  28. user = re.search(user_capacity,line)
  29. if device:
  30. pd['Device_Model'] = device.groups()[1].strip()
  31. if serial:
  32. pd['Serial_Number'] = serial.groups()[1].strip()
  33. if firmware:
  34. pd['Firmware_Version'] = firmware.groups()[1].strip()
  35. if user:
  36. pd['User_Capacity'] = user.groups()[1].strip()
  37. return pd
  38. if __name__ == '__main__':
  39. diskdata = getDiskInfo()
  40. print parserDiskInfo(diskdata)

3.内存抓取脚本:

  1. #!/usr/local/src/python/bin/python
  2. #-*- coding:utf-8 -*-
  3. from subprocess import PIPE,Popen
  4. import re
  5. import sys
  6. def getMemInfo():
  7. p = Popen(['dmidecode'],shell=False,stdout=PIPE)
  8. stdout, stderr = p.communicate()
  9. return stdout.strip()
  10. def parserMemInfo(memdata):
  11. line_in = False
  12. mem_str = ''
  13. pd = {}
  14. fd = {}
  15. for line in memdata.split('\n'):
  16. if line.startswith('Memory Device') and line.endswith('Memory Device'):
  17. line_in = True
  18. mem_str+='\n'
  19. continue
  20. if line.startswith('\t') and line_in:
  21. mem_str+=line
  22. else:
  23. line_in = False
  24. for i in mem_str.split('\n')[1:]:
  25. lines = i.replace('\t','\n').strip()
  26. for ln in lines.split('\n'):
  27. k, v = [i for i in ln.split(':')]
  28. pd[k.strip()] = v.strip()
  29. if pd['Size'] != 'No Module Installed':
  30. mem_info = 'Size:%s ; Part_Number:%s ; Manufacturer:%s' % (pd['Size'],pd['Part Number'],pd['Manufacturer'])
  31. for line in mem_info.split('\n'):
  32. for word in line.split(';'):
  33. k, v = [i.strip() for i in word.split(':')]
  34. fd[k] = v.strip()
  35. yield fd
  36. if __name__ == '__main__':
  37. memdata = getMemInfo()
  38. for i in parserMemInfo(memdata):
  39. print i

4.抓取服务器信息脚本:

  1. #!/usr/local/src/python/bin/python
  2. # -*- coding:utf-8 -*-
  3. from subprocess import PIPE,Popen
  4. import urllib, urllib2
  5. def getDMI():
  6. p = Popen('dmidecode',shell=True,stdout=PIPE)
  7. stdout, stderr = p.communicate()
  8. return stdout
  9. def parserDMI(dmidata):
  10. pd = {}
  11. fd = {}
  12. line_in = False
  13. for line in dmidata.split('\n'):
  14. if line.startswith('System Information'):
  15. line_in = True
  16. continue
  17. if line.startswith('\t') and line_in:
  18. k, v = [i.strip() for i in line.split(':')]
  19. pd[k] = v
  20. else:
  21. line_in = False
  22. name = "Manufacturer:%s ; Serial_Number:%s ; Product_Name:%s" % (pd['Manufacturer'],pd['Serial Number'],pd['Product Name'])
  23. for i in name.split(';'):
  24. k, v = [j.strip() for j in i.split(':')]
  25. fd[k] = v
  26. return fd
  27. if __name__ == '__main__':
  28. dmidata = getDMI()
  29. postdata = parserDMI(dmidata)
  30. print postdata

5.抓取主机信息

  1. #!/usr/local/src/python/bin/python
  2. #-*- coding:utf-8 -*-
  3. import platform
  4. def getHostInfo():
  5. pd ={}
  6. version = platform.dist()
  7. os_name = platform.node()
  8. os_release = platform.release()
  9. os_version = '%s %s' % (version[0],version[1])
  10. pd['os_name'] = os_name
  11. pd['os_release'] = os_release
  12. pd['os_version'] = os_version
  13. return pd
  14. if __name__ == '__main__':
  15. print getHostInfo()

6.抓取ip地址:

  1. #!/usr/local/src/python/bin/python
  2. #-*- coding:utf-8 -*-
  3. from subprocess import PIPE,Popen
  4. import re
  5. def getIpaddr():
  6. p = Popen(['ifconfig'],shell=False,stdout=PIPE)
  7. stdout, stderr = p.communicate()
  8. return stdout.strip()
  9. def parserIpaddr(ipdata):
  10. device = re.compile(r'(eth\d)')
  11. ipaddr = re.compile(r'(inet addr:[\d.]{7,15})')
  12. mac = re.compile(r'(HWaddr\s[0-9A-Fa-f:]{17})')
  13. link = re.compile(r'(Link encap:[\w]{3,14})')
  14. mask = re.compile(r'(Mask:[\d.]{9,15})')
  15. for lines in ipdata.split('\n\n'):
  16. pd = {}
  17. eth_device = re.search(device,lines)
  18. inet_ip = re.search(ipaddr,lines)
  19. hw = re.search(mac,lines)
  20. link_encap = re.search(link,lines)
  21. _mask = re.search(mask,lines)
  22. if eth_device:
  23. if eth_device:
  24. Device = eth_device.groups()[0]
  25. if inet_ip:
  26. Ipaddr = inet_ip.groups()[0].split(':')[1]
  27. if hw:
  28. Mac = hw.groups()[0].split()[1]
  29. if link_encap:
  30. Link = link_encap.groups()[0].split(':')[1]
  31. if _mask:
  32. Mask = _mask.groups()[0].split(':')[1]
  33. pd['Device'] = Device
  34. pd['Ipaddr'] = Ipaddr
  35. pd['Mac'] = Mac
  36. pd['Link'] = Link
  37. pd['Mask'] = Mask
  38. yield pd
  39. if __name__ == '__main__':
  40. ipdata = getIpaddr()
  41. for i in parserIpaddr(ipdata):
  42. print i

7.对这些信息进行合并,并通过API形式将数据发送给cmdb端

  1. #!/usr/local/src/python/bin/python
  2. import urllib, urllib2
  3. from cpuinfo import *
  4. from diskinfo import *
  5. from meminfo import *
  6. from product import *
  7. from hostinfo import *
  8. from ipaddress import *
  9. def getHostTotal():
  10. ld = []
  11. cpuinfo = parserCpuInfo(getCpuInfo())
  12. diskinfo = parserDiskInfo(getDiskInfo())
  13. for i in parserMemInfo(getMemInfo()):
  14. meminfo = i
  15. productinfo = parserDMI(getDMI())
  16. hostinfo = getHostInfo()
  17. ipaddr = parserIpaddr(getIpaddr())
  18. for i in ipaddr:
  19. ip = i
  20. for k in cpuinfo.iteritems():
  21. ld.append(k)
  22. for i in diskinfo.iteritems():
  23. ld.append(i)
  24. for j in meminfo.iteritems():
  25. ld.append(j)
  26. for v in productinfo.iteritems():
  27. ld.append(v)
  28. for x in hostinfo.iteritems():
  29. ld.append(x)
  30. for y in ip.iteritems():
  31. ld.append(y)
  32. return ld
  33. def parserHostTotal(hostdata):
  34. pg = {}
  35. for i in hostdata:
  36. pg[i[0]] = i[1]
  37. return pg
  38. def urlPost(postdata):
  39. data = urllib.urlencode(postdata)
  40. req = urllib2.Request('http://132.96.77.12:8000/api/collect',data)
  41. response = urllib2.urlopen(req)
  42. return response.read()
  43. if __name__ == '__main__':
  44. hostdata = getHostTotal()
  45. postdata = parserHostTotal(hostdata)
  46. print urlPost(postdata)

到目前为止,cmdb系统已经可以将所有客户端的主机信息写入到数据库,并且可以通过nagios端的API接口直接调到数据:

http://132.96.77.12:8000/api/gethosts.json

通过图可以看到,已经成功调用到API接口的数据。

接下来可以在nagios端进行调用API接口的数据,对数据进行格式化。并写入文件。

1.nagios脚本

  1. #!/opt/data/py/bin/python
  2. #!-*- coding:utf-8 -*-
  3. import urllib, urllib2
  4. import json
  5. import os
  6. import shutil
  7. CURR_DIR = os.path.abspath(os.path.dirname(__file__))
  8. HOST_CONF_DIR = os.path.join(CURR_DIR,'hosts')
  9. HOST_TMP = """define host {
  10. use linux-server
  11. host_name %(hostname)s
  12. check_command check-host-alive
  13. alias %(hostname)s
  14. address %(ipaddr)s
  15. contact_groups admins
  16. }
  17. """
  18. def getHosts():
  19. url = 'http://132.96.77.12:8000/api/gethosts.json'
  20. return json.loads(urllib2.urlopen(url).read())
  21. def initDir():
  22. if not os.path.exists(HOST_CONF_DIR):
  23. os.mkdir(HOST_CONF_DIR)
  24. def writeFile(f,s):
  25. with open(f,'w') as fd:
  26. fd.write(s)
  27. def genNagiosHost(hostdata):
  28. initDir()
  29. conf = os.path.join(HOST_CONF_DIR,'hosts.cfg')
  30. hostconf = ""
  31. for hg in hostdata:
  32. for h in hg['members']:
  33. hostconf+=HOST_TMP %h
  34. writeFile(conf,hostconf)
  35. return "ok"
  36. def main():
  37. result = getHosts()
  38. if result['status'] == 0:
  39. print genNagiosHost(result['data'])
  40. else:
  41. print 'Error: %s' % result['message']
  42. if os.path.exists(os.path.join(HOST_CONF_DIR,'hosts.cfg')):
  43. os.chdir(HOST_CONF_DIR)
  44. shutil.copyfile('hosts.cfg','/etc/nagios/objects/hosts.cfg')
  45. if __name__ == "__main__":
  46. main()

现在已经生成nagios主机的配置文件,并copy到nagios/objects目录下hosts.cfg。接下来可以测试是否nagios配置有问题,如果没有问题,就可以启动nagios服务

[root@yetcomm-v2 bin]# ./nagios -v /etc/nagios/nagios.cfg

通过测试,nagios没有发生错误或警告信息,现在可以启动nagios服务:

[root@yetcomm-v2 bin]# service nagios restart

最后,可以通过浏览器查看nagios的监控界面:   

通过上图,可以看到已经将一台主机加入到监控组。由于是生产环境,所有只能拿测试服务器进行测试。其实测试环境和生产环境的代码完全一致。

python+Django实现Nagios自动化添加监控项目的更多相关文章

  1. Python+Django+ansible playbook自动化运维项目实战☝☝☝

    Python+Django+ansible playbook自动化运维项目实战☝☝☝  一.入门引导 DevOPSDevOps(英文Development和Operations的组合)是一组过程.方法 ...

  2. Python+Django+ansible playbook自动化运维项目实战✍✍✍

    Python+Django+ansible playbook自动化运维项目实战  整个课程都看完了,这个课程的分享可以往下看,下面有链接,之前做java开发也做了一些年头,也分享下自己看这个视频的感受 ...

  3. Python+Django+Ansible Playbook自动化运维项目实战

    Python+Django+AnsiblePlaybook自动化运维项目实战 整个课程都看完了,这个课程的分享可以往下看,下面有链接,之前做java开发也做了一些年头,也分享下自己看这个视频的感受,单 ...

  4. zabbix的自动发现、自定义添加监控项目、配置邮件告警

    1.zabbix的自动发现这里的自动发现,所显示出来的是规则的上自动了现 然后 可以对其内容进行相关的配制,如时间或周期 注意:对于单个主机的规则,可以自行添加或删除, 但对于已经添加好了的规则,若需 ...

  5. 【转】python+django+vue搭建前后端分离项目

    https://www.cnblogs.com/zhixi/p/9996832.html 以前一直是做基于PHP或JAVA的前后端分离开发,最近跟着python风搭建了一个基于django的前后端分享 ...

  6. python+django+vue搭建前后端分离项目

    以前一直是做基于PHP或JAVA的前后端分离开发,最近跟着python风搭建了一个基于django的前后端分享项目 准备工作:IDE,[JetBrains PyCharm2018][webpack 3 ...

  7. zabbix添加自定义监控项目

    在zabbix里添加一个自定义监控项目,简单做个笔记,怕忘了 首先需要定义 zabbix_agentd.conf  中的 UnsafeUserParameters 修改为 UnsafeUserPara ...

  8. Django-Multitenant,分布式多租户数据库项目实战(Python/Django+Postgres+Citus)

    Python/Django 支持分布式多租户数据库,如 Postgres+Citus. 通过将租户上下文添加到您的查询来实现轻松横向扩展,使数据库(例如 Citus)能够有效地将查询路由到正确的数据库 ...

  9. Python(Django)项目与Apache的管理

    (开开心心每一天~ ---虫瘾师) Python(Django)项目交给Apache的管理(一) 准备:Django的环境(Python).Apache.Wsgi(必须文件) 首先需要电脑有Pytho ...

随机推荐

  1. Oracle Apex 有用笔记系列 6 - 可编辑交互报告 Editable Interactive Report

    据笔者所知.Apex 4.x 是没有提供可编辑交互报告组件的.这就须要我们手动实现. 事实上这也并非非常复杂,仅仅须要简单几步. 1. 依据向导建立一个interactive report.查询语句能 ...

  2. Objective-C基础笔记(6)Block

    Block(代码段)封装了一段代码,能够在不论什么时候运行. Block能够作为函数參数或者函数返回值,而其本身又能够带输入參数或返回值.它和传统的函数指针非常相似,可是有差别:block是inlin ...

  3. centos 使用 CP 命令 不提示 覆盖

    今天 在我的VPS上拷一个目录,但放的地方有一个同名目录并且里面还有文件.如是直接拷过去,结果有N个要确认替换的提示,直接CTRL+C,在网上搜了把,发现有几个方法能够解决,方法例如以下: 一般我们使 ...

  4. 【转载】C#扫盲之:带你掌握C#的扩展方法、以及探讨扩展方法的本质、注意事项

    1.为什么需要扩展方法 .NET3.5给我们提供了扩展方法的概念,它的功能是在不修改要添加类型的原有结构时,允许你为类或结构添加新方法. 思考:那么究竟为什么需要扩展方法呢,为什么不直接修改原有类型呢 ...

  5. STL源代码剖析——基本算法stl_algobase.h

    前言 在STL中.算法是常常被使用的,算法在整个STL中起到很关键的数据.本节介绍的是一些基本算法,包括equal.fill.fill_n,iter_swap.lexicographical_comp ...

  6. Android API Guides---NFC Basics

    本文档介绍了Android中运行基本任务NFC. 它说明了怎样在NDEF消息的形式发送和接收数据的NFC并介绍了支持这些功能的Andr​​oid框架的API. 对于更高级的主题.包含与非NDEF数据工 ...

  7. C#基础系列:反射笔记

    前言:使用反射也有几年了,但是一直觉得,反这个概念很抽象,今天有时间就来总结下这个知识点. 1.为什么需要反射: 最初使用反射的时候,作为小菜总是不理解,既然可以通过new 一个对象的方式得到对象,然 ...

  8. session自己定义存储,怎样更好地进行session共享;读tomcat7源代码,org.apache.catalina.session.FileStore可知

    session自己定义存储.怎样更好地进行session共享: 读tomcat源代码,org.apache.catalina.session.FileStore可知 一.详见: 方法1 public ...

  9. Linux struct itimerval使用方法

    版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/hbuxiaofei/article/details/35569229 先看一段代码 #include ...

  10. GNU linux 中makefile那点事

    转自陈皓: http://bbs.chinaunix.net/viewthread.php?tid=408225 概述—— 什么是makefile?或许很多Winodws的程序员都不知道这个东西,因为 ...