
暂无个人介绍
用chrome连接nginx服务器(nginx+spero),发现每次请求结果返回给浏览器后,会过一会才会运行 ngx_http_close_connection函数,可以看到nginx返回给chrome的header和结果是: HTTP/1.1 200 OK Server: nginx Date: Fri, 15 Apr 2016 08:39:50 GMT Content-Type: text/plain Content-Length: 28 Connection: keep-alive Keep-Alive: timeout=5 spero return ads, status 200 而通过curl访问,也是返回同样的结果,但是nginx会立刻调用ngx_http_close_connection函数,看起来keep-alive没有起作用,猜测是curl拿到结果后立马主动关闭连接。 HTTP/1.1 200 OK Server: nginx Date: Fri, 15 Apr 2016 08:44:11 GMT Content-Type: text/plain Content-Length: 28 Connection: keep-alive Keep-Alive: timeout=5 spero return ads, status 200 那么做一个实验:设置nginx的配置文件,将keep-alive关掉,看看chrome访问时是否ngx_http_close_connection函数立刻被调用? 首先,用命令:keepalive_timeout 0 禁用长连接,则看到header中的Connection为close HTTP/1.1 200 OK Server: nginx Date: Fri, 15 Apr 2016 08:50:05 GMT Content-Type: text/plain Content-Length: 28 Connection: close spero return ads, status 200 同时,在nginx print的log中也可以看到,ngx_http_finalize_request函数之后,ngx_http_close_connection函数立刻就被调用了。 在spero项目中,长连接必须被关闭以支持大并发请求。 本文转自 zhegaozhouji 51CTO博客,原文链接:http://blog.51cto.com/1038741/1764232
1 2 3 4 5 6 7 8 import os old_file_name = input("Please input what's file do you want to copy go:") fp = open(old_file_name) content = fp.read() index = old_file_name.rfind('.') new_file_name = old_file_name[:index]+"[复件]"+old_file_name[index:] dp = open(new_file_name,'w') dp.write(content) 上面代码是文件的复制,我们的思路是这样的: 你可以打开一个存在的文件,然后去读取这个文件的内容,然后去创建一个新的文件,这个文件的名字是旧文件名字后面加上[复件]这样的字体。然后把我们刚刚在旧文件中读到的内容写到新文件里面去。关闭两个文件就好啦。 第二行让用户输入你想复制的文件,这个文件必须存在,而且最好是绝对路径。 第四行是打开我们要旧文件,用content变量是保存旧文件里面的内容 第五行去查找old_file_name这个变量的字符串中最右边出现的一个'.'符号的下标。 第六行是给new文件命名,然后赋予给变量new_file_name这个变量啊 那么上面有一个问题,如果说我们要复制一个你不知多大的文件的时候,千万不要用read,因为read会把所有的内容都读进内存,如果这个文件很大你的内存就崩了,也不要用readlines因为如果你的文件内容只有一行,这一行的数据很大,那你的内存也会被影响到。 可以用下面代码: 1 2 3 4 5 6 7 8 9 10 11 12 13 import os old_file_name = input("Please input what's file do you want to copy go:") fp = open(old_file_name) index = old_file_name.rfind('.') new_file_name = old_file_name[:index]+"[复件]"+old_file_name[index:] dp = open(new_file_name,'w') while True: content = fp.read(1024) if len(content) == 0: break dp.write(content) fp.close() dp.close() 上面代码的第8行是读这个文件的前1024个字符,然后再去判断读出来的内容是不是为空的,如果是的话就break退出循环,如果不是就就把内容写入新文件中 本文转自 周子琪 51CTO博客,原文链接:http://blog.51cto.com/izhouyu/1967644
文章出自:http://sys.firnow.com/linux/x8002010n08m/27s90182641.html 1、依赖关系的解决: 需要事先下载并安装GeoIP和GetIP-devel两个rpm包; # yum -y --nogpgcheck localinstall GeoIP-*.el5.i386.rpm 接着是ettercap相关的rpm包(ettercap,ettercap-common,需要下载,这里没指定具体的版本号,你可以根据自己的实际情况进行安装): # yum -y --nogpgcheck localinstall ettercap-*.rpm 而后安装开发环境,尤其是以下几个rpm包: # yum install libpcap libpcap-devel gdbm gdbm-devel zlib zlib-devel 2、安装ntop # useradd -M -s /sbin/nologin -r ntop # tar zxvf ntop-4.0.1.tar.gz # cd ntop-4.0.1 # ./autogen.sh # make # make install # chown -R ntop:ntop /usr/local/share/ntop # chown -R ntop:root /usr/local/var/ntop 3、配置并启动ntop 首先为ntop的admin用户设置密码: # ntop -A 接下来启动ntop: # ntop -i eth0 -d -L -u ntop 使之开机自动启动: echo 'ntop -i eth0 -d -L -u ntop &> /dev/null' >> /etc/rc.d/rc.local 4、将其与cacti整合在一起(需要一个事先已经安装完成的cacti): 首先去下载cacti的ntop插件,而后解压至cacti的插件目录: # tar zxvf ntop-0.1.tar.gz -C /var/www/html/cacti/plugins/ 接着配置cacti的主配置文件,启用此插件: # vim /var/www/html/cacti/include/config.php 添加如下内容: $plugins[] = 'ntop'; 接下来到cacti的控制台中"settings"中配置此插件,将其指向实际的ntop服务器所在的URL;然后再到cacti控制台的"user Management"中的admin用户中启用此插件即可。 文章出处:飞诺网(www.firnow.com):http://sys.firnow.com/linux/x8002010n08m/27s90182641.html 本文转自holy2009 51CTO博客,原文链接:http://blog.51cto.com/holy2010/405815
以下在11.2.0.3上,2 cores+ext3文件系统, 导出schema下10G数据,使用compression+ parallel=2 ,耗时大越10分钟, 生成的dump文件总共4.7GB大小 [oracle@mlab1 ~]$ expdp dumpfile=HDUMP:bcm%U.dmp filesize=2048M compression=all schemas=bcm parallel=2 logfile=HDUMP:bcm.log Export: Release 11.2.0.3.0 - Production on Wed Sep 26 11:56:19 2012 Copyright (c) 1982, 2011, Oracle and/or its affiliates. All rights reserved. Username: / as sysdba Connected to: Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production With the Partitioning, Automatic Storage Management, OLAP, Data Mining and Real Application Testing options Starting "SYS"."SYS_EXPORT_SCHEMA_01": /******** AS SYSDBA dumpfile=HDUMP:bcm%U.dmp filesize=2048M compression=all schemas=bcm parallel=2 logfile=HDUMP:bcm.log Estimate in progress using BLOCKS method... Processing object type SCHEMA_EXPORT/TABLE/TABLE_DATA Total estimation using BLOCKS method: 10.82 GB Processing object type SCHEMA_EXPORT/USER Processing object type SCHEMA_EXPORT/SYSTEM_GRANT Processing object type SCHEMA_EXPORT/ROLE_GRANT Processing object type SCHEMA_EXPORT/DEFAULT_ROLE Processing object type SCHEMA_EXPORT/PRE_SCHEMA/PROCACT_SCHEMA Processing object type SCHEMA_EXPORT/TABLE/TABLE Processing object type SCHEMA_EXPORT/PROCEDURE/PROCEDURE Processing object type SCHEMA_EXPORT/PROCEDURE/ALTER_PROCEDURE Processing object type SCHEMA_EXPORT/TABLE/INDEX/INDEX Processing object type SCHEMA_EXPORT/TABLE/CONSTRAINT/CONSTRAINT Processing object type SCHEMA_EXPORT/TABLE/INDEX/STATISTICS/INDEX_STATISTICS . . exported "BCM"."C_CUSTOMER" 1.194 GB 3000000 rows . . exported "BCM"."C_STOCK" 2.311 GB 10000000 rows . . exported "BCM"."C_ORDER_LINE" 809.8 MB 30004095 rows . . exported "BCM"."E_TRADE" 81.05 MB 4419000 rows . . exported "BCM"."E_SETTLEMENT" 19.90 MB 4590000 rows . . exported "BCM"."E_CASH_TRANSACTION" 32.58 MB 4383000 rows . . exported "BCM"."E_DAILY_MARKET" 33.43 MB 3861000 rows . . exported "BCM"."C_HISTORY" 56.62 MB 3000115 rows . . exported "BCM"."E_TRADE_HISTORY" 6.042 MB 4481000 rows . . exported "BCM"."C_ORDER" 15.22 MB 3000128 rows . . exported "BCM"."E_WATCH_ITEM" 17.15 MB 4414000 rows . . exported "BCM"."E_FINANCIAL" 40.82 MB 1000000 rows . . exported "BCM"."E_ACCOUNT_PERMISSION" 9.659 MB 710000 rows . . exported "BCM"."E_NEWS_ITEM" 1.133 MB 100000 rows . . exported "BCM"."E_CUSTOMER" 3.526 MB 100000 rows . . exported "BCM"."E_ADDRESS" 1.731 MB 150000 rows . . exported "BCM"."E_COMPANY" 826.3 KB 50000 rows . . exported "BCM"."C_DISTRICT" 67.51 KB 1000 rows . . exported "BCM"."C_ITEM" 5.609 MB 100000 rows . . exported "BCM"."E_CUSTOMER_ACCOUNT" 6.697 MB 500000 rows . . exported "BCM"."C_WAREHOUSE" 12.47 KB 100 rows . . exported "BCM"."E_BROKER" 9.898 KB 1000 rows . . exported "BCM"."E_CHARGE" 4.968 KB 15 rows . . exported "BCM"."E_COMMISSION_RATE" 5.937 KB 240 rows . . exported "BCM"."E_COMPANY_COMPETITOR" 703.2 KB 150000 rows . . exported "BCM"."C_NEW_ORDER" 744.1 KB 900088 rows . . exported "BCM"."E_EXCHANGE" 5.468 KB 4 rows . . exported "BCM"."E_INDUSTRY" 6.460 KB 102 rows . . exported "BCM"."E_CUSTOMER_TAXRATE" 413.0 KB 200000 rows . . exported "BCM"."E_NEWS_XREF" 471.7 KB 100000 rows . . exported "BCM"."E_LAST_TRADE" 485.3 KB 68500 rows . . exported "BCM"."E_SECTOR" 5.039 KB 12 rows . . exported "BCM"."E_STATUS_TYPE" 4.867 KB 5 rows . . exported "BCM"."E_TAXRATE" 8.703 KB 320 rows . . exported "BCM"."E_TRADE_TYPE" 5.062 KB 5 rows . . exported "BCM"."E_SECURITY" 2.177 MB 68500 rows . . exported "BCM"."E_WATCH_LIST" 252.6 KB 100000 rows . . exported "BCM"."E_HOLDING" 0 KB 0 rows . . exported "BCM"."E_HOLDING_HISTORY" 0 KB 0 rows . . exported "BCM"."E_HOLDING_SUMMARY" 0 KB 0 rows . . exported "BCM"."E_TRADE_REQUEST" 0 KB 0 rows . . exported "BCM"."E_ZIP_CODE" 103.3 KB 14741 rows Master table "SYS"."SYS_EXPORT_SCHEMA_01" successfully loaded/unloaded ****************************************************************************** Dump file set for SYS.SYS_EXPORT_SCHEMA_01 is: /home/oracle/dump/bcm01.dmp /home/oracle/dump/bcm02.dmp /home/oracle/dump/bcm03.dmp /home/oracle/dump/bcm04.dmp Job "SYS"."SYS_EXPORT_SCHEMA_01" successfully completed at 12:05:03 [oracle@mlab1 ~]$ cd /home/oracle/dump/ [oracle@mlab1 dump]$ ls -lh total 4.7G -rw-r----- 1 oracle asmadmin 2.0G Sep 26 12:03 bcm01.dmp -rw-r----- 1 oracle asmadmin 2.0G Sep 26 12:04 bcm02.dmp -rw-r----- 1 oracle asmadmin 521M Sep 26 12:05 bcm03.dmp -rw-r----- 1 oracle asmadmin 121M Sep 26 12:05 bcm04.dmp -rw-r--r-- 1 oracle asmadmin 4.9K Sep 26 12:05 bcm.log 由于以上dump文件已被压缩过,所以后续的bzip2或者gz压缩几乎没有意义,而且耗时超长且压缩比极低: 本文转自maclean_007 51CTO博客,原文链接:http://blog.51cto.com/maclean/1278102
因为家里使用ADSL动态IP上网,有时在外面需要使用家里资源,原本使用的是TP-LINK自带的花生壳解析,用过之后发现很不稳定。因为自己注册了域名也已使用了DNSPOD解析。 1.新建脚本文件 1 vim ddns.sh 文件内容如下: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 #!/bin/sh ################################################# # AnripDdns v3.08.09 # 基于DNSPod用户API实现的动态域名客户端 # 作者: 若海[mail@anrip.com] # 介绍: http://www.anrip.com/ddnspod # 时间: 2013-08-08 23:25:00 ################################################# # 全局变量表 arPass=arMail="" # 获得外网地址 arIpAdress() { local inter="http://members.3322.org/dyndns/getip" wget --quiet --no-check-certificate --output-document=- $inter } # 查询域名地址 # 参数: 待查询域名 arNslookup() { local dnsvr="114.114.114.114" nslookup ${1} $dnsvr | tr -d '\n[:blank:]' | sed 's/.\+1 \([0-9\.]\+\)/\1/' } # 读取接口数据 # 参数: 接口类型 待提交数据 arApiPost() { local agent="AnripDdns/3.08(mail@anrip.com)" local inter="https://dnsapi.cn/${1:?'Info.Version'}" local param="login_email=${arMail}&login_password=${arPass}&format=json&${2}" wget --quiet --no-check-certificate --output-document=- --user-agent=$agent --post-data $param $inter } # 更新记录信息 # 参数: 主域名 子域名 arDdnsUpdate() { local domainID recordID recordRS recordCD # 获得域名ID domainID=$(arApiPost "Domain.Info" "domain=${1}") domainID=$(echo $domainID | sed 's/.\+{"id":"\([0-9]\+\)".\+/\1/') # 获得记录ID recordID=$(arApiPost "Record.List" "domain_id=${domainID}&sub_domain=${2}") recordID=$(echo $recordID | sed 's/.\+\[{"id":"\([0-9]\+\)".\+/\1/') # 更新记录IP recordRS=$(arApiPost "Record.Ddns" "domain_id=${domainID}&record_id=${recordID}&sub_domain=${2}&record_line=默认") recordCD=$(echo $recordRS | sed 's/.\+{"code":"\([0-9]\+\)".\+/\1/') # 输出记录IP if [ "$recordCD" == "1" ]; then echo $recordRS | sed 's/.\+,"value":"\([0-9\.]\+\)".\+/\1/' return 1 fi # 输出错误信息 echo $recordRS | sed 's/.\+,"message":"\([^"]\+\)".\+/\1/' } # 动态检查更新 # 参数: 主域名 子域名 arDdnsCheck() { local postRS local hostIP=$(arIpAdress) local lastIP=$(arNslookup "${2}.${1}") echo "hostIP: ${hostIP}" echo "lastIP: ${lastIP}" if [ "$lastIP" != "$hostIP" ]; then postRS=$(arDdnsUpdate $1 $2) echo "postRS: ${postRS}" if [ $? -ne 1 ]; then return 0 fi fi return 1 } ################################################### # 设置用户参数 arMail="user@anrip.com" arPass="anrip.net" # 检查更新域名 arDdnsCheck "anrip.com" "lab" arDdnsCheck "anrip.net" "lab" ps:以上代码来自http://www.anrip.com/post/872 我们只需要将上面的 # 设置用户参数 arMail="user@anrip.com" //DNSPOD用户名 arPass="anrip.net" //DNSPOD密码 # 检查更新域名 arDdnsCheck"anrip.com" "lab" //需要更新的域名为anrip.com,主机为lab,就是lab.anrip.com arDdnsCheck"anrip.net" "lab" //更新lab.anrip.net 修改成自己的信息即可 3.增加执行权限 1 chmod +x /root/ddns.sh 4.加入任务计划(5分钟执行一次) 1 echo "*/5 * * * * root /root/ddns.sh" >> /etc/crontab 计划任务执行情况可以查看/var/log/cron 说明: 如果在执行后发现 1 2 3 4 5 [root@localhost ~]# ./ddns.sh ./ddns.sh: line 24: nslookup: command not found hostIP: 114.234.77.222 lastIP: postRS: 114.234.77.222 如果你使用的是CentOS则执行 1 yum -y install bind-utils 或者是ubuntu的话 1 sudo apt-get install dnsutils 本文转自 rong341233 51CTO博客,原文链接:http://blog.51cto.com/fengwan/1404534
什么是Sphinx/Coreseek Sphinx是一个在GPLv2下分发的全文检索引擎;Coreseek是一个可供企业使用的、基于Sphinx(可独立于Sphinx原始版本运行)的中文全文检索引擎,按照GPLv2协议发行,商业使用(例如, 嵌入到其他程序中)需要联系我们以获得商业授权。 一般而言,Sphinx是一个独立的全文搜索引擎;而Coreseek是一个支持中文的全文搜索引擎,意图为其他应用提供高速、低空间占用、高结果相关度的中文全文搜索能力。Sphinx/Coreseek可以非常容易的与SQL数据库和脚本语言集成。 当前系统内置MySQL和PostgreSQL 数据库数据源的支持,也支持从管道标准输入读取入特定格式的XML数据。通过修改源代码,用户可以自行增加新的数据源(例如:其他类型的DBMS的原生支持)。在最新的版本中,用户还可以使用Python脚本作为数据源来获取任何已知世界和未知世界的数据,这极大的扩展了数据源的来源。 搜索API支持PHP、Python、Perl、Rudy和Java,并且也可以用作MySQL存储引擎。搜索API非常简单,可以在若干个小时之内移植到新的语言上。 Sphinx 是SQL PhraseIndex的缩写,但不幸的和CMU的Sphinx项目重名。 Coreseek http://www.coreseek.cn 为Sphinx在中国地区的用户提供支持服务. Sphinx http://sphinxsearch.com/ Sphinx/Coreseek 的特性 高速的建立索引(在当代CPU上,峰值性能可达到10MB/秒); 高性能的搜索(在2 – 4GB 的文本数据上,平均每次检索响应时间小于0.1秒); 可处理海量数据(目前已知可以处理超过100GB的文本数据, 在单一CPU的系统上可处理100 M 文档); 提供了优秀的相关度算法,基于短语相似度和统计(BM25)的复合Ranking方法; 支持分布式搜索; 提供文档片段(摘要以及高亮)生成功能; 可作为MySQL的存储引擎提供搜索服务; 支持布尔、短语、词语相似度等多种检索模式; 文档支持多个全文检索字段(缺省配置下,最大不超过32个); 文档支持多个额外的属性信息(例如:分组信息,时间戳等); 停止词查询; 支持单一字节编码和UTF-8编码,以及对GBK和BIG5的完善支持; 支持英语、俄语词词干化和Soundex,以便进行词形学处理; 原生的MySQL支持(同时支持MyISAM 和InnoDB ); 原生的PostgreSQL支持; 支持直接模拟为MySQL服务端运行; 支持MMSeg分词引擎,用户可自定义词典; Python数据源支持,得以获取任何已知世界和未知世界的数据. 目前,Sphinx/Coreseek的发布包包括如下软件: indexer: 用于创建全文索引; search: 一个简单的命令行(CLI) 的测试程序,用于测试全文索引; searchd: 一个守护进程,其他软件可以通过这个守护进程进行全文检索; sphinxapi: 一系列searchd 的客户端API 库,用于流行的Web脚本开发语言(PHP, Python, Perl, Ruby, Java). spelldump: 一个简单的命令行工具,用于从 ispell 或 MySpell (OpenOffice内置绑定) 格式的字典中提取词条。当使用 wordforms 时可用这些词条对索引进行定制. indextool: 工具程序,用来转储关于索引的多项调试信息。此工具是从版本Coreseek 3.1(Sphinx 0.9.9-rc2)开始加入的。 mmseg: 工具程序和库,Coreseek用于提供中文分词和词典处理。 安装前准备环境 yum install make gcc g++ gcc-c++ libtool make mysql-devel libxml2-devel expat-devel 官网参考地址:http://www.coreseek.cn/products/products-install/install_on_bsd_linux/RHEL5-5/ 来到官网http://www.coreseek.com/下载Coreseek 3.2.14稳定版,解压进入目录。 # tar xf coreseek-3.2.14.tar.gz # cd coreseek-3.2.14 配置语言支持中文 # export LANG="zh_CN.UTF-8" # export LC_ALL="zh_CN.UTF-8" # cat testpack/var/test/test.xml 安装coreseek开发的mmseg,为coreseek提供中文分词功能 # cd mmseg-3.2.14/ # ./bootstrap # ./configure --prefix=/usr/local/mmseg3 # make && make install 中文分词测试 # /usr/local/mmseg3/bin/mmseg -d /usr/local/mmseg3/etc src/t1.txt 中文/x 分/x 词/x 测试/x 中国人/x 上海市/x Word Splite took: 0 ms. 安装coreseek # cd csft-3.2.14/ # sh buildconf.sh 1 ./configure --prefix=/alidata/server/sphinx/coreseek --without-python --without-unixodbc --with-mmseg --with-mmseg-includes=/alidata/server/sphinx/mmseg3/include/mmseg --with-mmseg-libs=/alidata/server/sphinx/mmseg3/lib/ --with-mysql=/alidata/server/mysql --with-mysql-includes=/alidata/server/mysql/include/ # make && make install 测试是否可以正常运行 # /usr/local/coreseek/bin/indexer -c /usr/local/coreseek/etc/sphinx-min.conf.dist csft-4.0版显示:ERROR: nothing to do. coreseek中文全文检索测试 # cd testpack/ # /usr/local/coreseek/bin/indexer -c etc/csft.conf 索引全部数据 # /usr/local/coreseek/bin/indexer -c etc/csft.conf -all 索引指定数据 # /usr/local/coreseek/bin/indexer -c etc/csft.conf xml 测试搜索 # /usr/local/coreseek/bin/search -c etc/csft.conf 测试搜索关键词 # /usr/local/coreseek/bin/search -c etc/csft.conf -a hello欢迎来到北京清华大学 开启搜索服务 # /usr/local/coreseek/bin/searchd -c etc/csft.conf # 如要已启动服务,要更新索引,请使用 /usr/local/coreseek/bin/indexer-c etc/csft.conf --all --rotate # 如要停止搜索服务,请使用 /usr/local/coreseek/bin/searchd-c etc/csft.conf --stop 然后,请参考csft-3.2.14下api目录中的相关文件,使用PHP、Python、Ruby、Java来测试搜索服务;也可以前往< ahref="/products-install/step_by_step/">搜索服务建立三步曲,查看第三步使用PHP测试。 通过以上步骤,coreseek已经安装测试完成,可以提供正常的xml数据源索引以及提供对应的搜索服务了,下一步工作,请查看手册,准备好mysql数据信息,以及进行mysql数据源的测试,并在您的应用中调用搜索服务;mysql数据源的配置可参考testpack/etc/csft_mysql.conf文件 官方文档地址:http://www.coreseek.cn/docs/coreseek_3.2-sphinx_0.9.9.html 快速安装地址:http://www.coreseek.cn/product_install/install_on_bsd_linux/#mysql 在实现以上功能之后,即可开始下面的实验。 LAMP+Coreseek+sphinx构建中文检索引擎 安装好LAMP环境,并将它们启动(略),在前面的文章中都有讲到。 1、 先给数据库插入一些数据,用于测试,在解压coreseek源码包后可以在/coreseek-4.1-beta/testpack/var/test/找到.sql的数据库脚本文件,导入数据库即可。 2、 安装PHP的sphinx扩展 可以在这里(http://pecl.php.net/package/sphinx)找到sphinx的php扩展源码,注意,使用phpize,configure的时候可能会要求要安装libsphinxclient,它在coreseek-4.1-beta/csft-4.1/api/libsphinxclient/里面能找到,编译安装它以后就可以configure,make,生成动态so文件了。 3、 给服务提供配置文件 (源码目录下有样例: /coreseek-4.1-beta/testpack/etc/csft_mysql.conf) #源定义 source study { type = mysql sql_host = localhost sql_user = root sql_pass = sql_db = test sql_port = 3306 sql_query_pre = SET NAMES utf8 sql_query = select id,title,content,group_id from documents; // 这里使用select 将想要被用于检索的索引字段查出来,缓存于Sphinx服务器中,sql_query第一列id需为整数,title、content作为字符串/文本字段,被全文索引 sql_query_info = SELECT * FROM documents where id=$id #仅被命令行搜索所用,用来获取和显示文档信息,目前仅对MySQL有效,且仅用于调试目的。此查询为每个文档ID获取CLI搜索工具要显示的文档信息。它需要包含$id宏,以此来对应到查询的文档的ID。 } #index定义 index study { source = study #对应的source名称 path = /usr/local/coreseek/var/data/study docinfo = extern mlock = 0 morphology = none //不使用任何词形处理器 min_word_len = 1 //最小索引词长度。可选选项,默认为1(索引任何词) html_strip = 0 charset_dictpath = /usr/local/mmseg3/etc/ //设置中文分词词典所在的目录 #charset_dictpath = etc/ charset_type = zh_cn.utf-8 } source mysql { type = mysql sql_host = localhost sql_user = root sql_pass = sql_db = tuchao sql_port = 3306 sql_query_pre = SET NAMES utf8 sql_query = SELECT id, title, abstract FROM ic_video sql_query_info = SELECT * FROM ic_video where id=$id } index mysql { source = mysql path = /usr/local/coreseek/var/data/mysql docinfo = extern mlock = 0 morphology = none min_word_len = 1 html_strip = 0 charset_dictpath = /usr/local/mmseg3/etc/ #charset_dictpath = etc/ charset_type = zh_cn.utf-8 } source qupeiyin { type = mysql sql_host = localhost sql_user = root sql_pass = sql_db = tuchao2 sql_port = 3306 sql_query_pre = SET NAMES utf8 sql_query = SELECT id, title, description FROM course sql_query_info = SELECT * FROM course where id=$id } index qupeiyin { source = qupeiyin path = /usr/local/coreseek/var/data/qupeiyin docinfo = extern mlock = 0 morphology = none min_word_len = 1 html_strip = 0 charset_dictpath = /usr/local/mmseg3/etc/ #charset_dictpath = etc/ charset_type = zh_cn.utf-8 } #全局index定义 indexer { mem_limit = 128M //索引过程内存限制,indexer不会超越的强制内存限制,设置太低会影响索引速度,一般为256M~1024M,最大限制是2048M. } #searchd服务定义 searchd { listen = 9312 read_timeout = 5 //网络客户端请求的读超时时间, searchd 强制关闭在此时间内未能成功发出查询的客户端连接。 max_children = 30 //子进程的最大数量,任何时候不可能有比此设置值更多的搜索同时运行。当达到限制时,新的输入客户端会被用临时失败(SEARCH_RETRY)状态码驳回; max_matches = 1000 //为每个索引所保持并返回给客户端的匹配数目的最大值 seamless_rotate = 1 //启用无缝轮换,数据轮换时不暂停搜索服务。 preopen_indexes = 0 unlink_old = 1 //索引轮换成功之后,是否删除以.old为扩展名的索引拷贝。可选选项,默认为1(删除这些索引拷贝)。 pid_file = /usr/local/coreseek/var/log/searchd_mysql.pid log = /usr/local/coreseek/var/log/searchd_mysql.log query_log = /usr/local/coreseek/var/log/query_mysql.log } 在写配置文件的时候,sourece名称可以与index名称不一样,但是path后的名称一定要和index定义的名称一致。 4、提供服务启动脚本 #!/bin/bash # # searchd - this script start and stop the searchd daemon # # chkconfig - 85 20 # description: # # processname: searchd # config: /usr/local/coreseek/etc/csft_mysql.conf . /etc/rc.d/init.d/functions searchd="/usr/local/coreseek/bin/searchd" prog=$(basename $searchd) conf_file="/usr/local/coreseek/etc/csft_mysql.conf" lockfile="/var/lock/subsys/searchd" start() { [ -e $lockfile ] && echo "searchd is already start" && exit 0 [ -x $searchd ] || exit 1 [ -f $conf_file ] || exit 2 echo -n "Starting $prog:" daemon $searchd -c $conf_file retval=$? echo if [ $retval -eq 0 ]; then touch $lockfile else echo "$prog is starting failed" fi return $retval } stop() { echo -n $"Stopping $prog:" killproc $prog -QUIT retval=$? echo if [ $retval -eq 0 ]; then rm -rf $lockfile fi return $retval } restart() { stop sleep 1 start } indexer() { /usr/local/coreseek/bin/indexer -c $conf_file --all } case "$1" in start) start ;; stop) stop ;; restart) restart ;; indexer) indexer ;; *) echo "Usage:$0 {start|stop|restart|indexer}" exit 2 esac 5、 重建全部索引 # /etc/init.d/searchd indexer 6、 启动searchd服务 # service searchd start 7、 提供PHP测试程序 <?php $s = new SphinxClient; $s->setServer("localhost", 9312); $s->setArrayResult(true); $s->setSelect(); $s->setMatchMode(SPH_MATCH_ALL); //SPH_MATCH_ALL这个检索方法表示只显示匹配到的数据ID,并进行分词。SPH_MATCH_ANY表示先将搜索的内容进行分词,输出每个分词匹配到的数据ID。 $result1 = $s->query('乔布斯','mysql'); $result2 = $s->query('搞笑','qupeiyin'); $result3 = $s->query('Google','study'); print_r($result1); print_r($result2); print_r($result3); ?> 8、测试服务 我可以在httpd服务器指定的目录下创建一个test.php拷贝以上代码,根据自己的数据库数据做更改后保存。 这一句我要讲下: $result1 = $s->query('乔布斯','mysql'); “乔布斯“是搜索的关键词,后面的’mysql ’对应的是定义在csft_mysql.conf中的索引名称。表示从哪个索引中找 以下是用浏览器访问test.php返回的结果: 首先返回结果是在mysql索引中搜索关键词‘乔布斯’ 的,可以看到在id=>38 、id=>39 有匹配到,而且对搜集内容进行了分词。 [matches] => Array ( [0] => Array ([id] => 38 [weight] => 6 [attrs] => Array ( ) ) [1] => Array ( [id]=> 39 [weight] => 3 [attrs] => Array ( ) ) ) [total] => 2 [total_found]=> 2 [time] => 0.002 [words] => Array ( [乔] =>Array ( [docs] => 2 [hits] => 3 ) [布] => Array ([docs] => 2 [hits] => 3 ) [斯] => Array ( [docs] => 2 [hits] => 3 ) ) ) 我们上MySQL服务器查找对应ID来验证: 我们再分析后续的输出结果,在qupeiyin索引中搜索‘ 搞笑’ 关键词,这里可以看到在id=>29 、 id=>518 有匹配到. Array ( [error] => [warning] =>[status] => 0 [fields] => Array ( [0] => title [1] => description )[attrs] => Array ( ) [matches] => Array ( [0] => Array ( [id] => 29 [weight] => 1 [attrs] => Array () ) [1] => Array ( [id] => 518 [weight]=> 1 [attrs] => Array ( ) ) ) [total] => 2 [total_found] => 2[time] => 0.002 [words] => Array ( [搞笑] => Array ([docs] => 2 [hits] => 2 ) ) ) 我们再来到数据库验证: 第三个输出也是可以找到对应的数据的,笔者就不上图了,由此可以看出,在对应的ID号确实能找到匹配的数据。 本文转自qw87112 51CTO博客,原文链接:http://blog.51cto.com/tchuairen/1585871
ris-linux是一个可以在linux平台上提供网络安装windows的服务(这需要客户端PC的网卡支持PXE协议),在微软的解决方案中与之相对应的是从Windows 2000 server开始提供的RIS服务。 下载地址 : wget http://ris-autoinst.googlecode.com/files/ris-autoinst-0.6.1.tar.gz ris-autoinst 0.6 安装手册 注:以下操作默认以管理员身份进行 一、准备步骤: 1. 以最小化安装CentOS 5.1,即:安装选择包时进入“立即自定义”,把所有的软件包前的勾去除。具体安装方法在此不作详解。 2. 禁用CentOS 5.1的SELinux (1) vi /etc/sysconfig/selinux/config 把SELINUX=enforcing改为SELINUX=disabled (2) reboot (重启) 3. 使用scp等方法把ris-autoinst-0.6.tar.gz复制到CentOS 5.1中的任意目录中 二、安装步骤: 1. 挂载CentOS 5.1光盘 mount CentOS 5.1 DVD to /mnt/centos5 2. 挂载Windows光盘,可只挂载一个 mount Windows XP CD to /mnt/winxp mount Windows 2003 CD to /mnt/win2003 注意:挂载目录必須为:/mnt/centos5,/mnt/winxp,/mnt/win2003如果你要更改,则必須修改config.sh文件,把其中的CENTOSPATH、WINXPPATH及W2K3PATH变量改成你实际的挂载目录。 3. 解压缩安装包并进入安装目录 tar xvzf ris-autoinst-0.6.tar.gz cd ris 4. 修改config.sh文件,把LOCALIP,LOCALNET,LOCALDNS,LOCALROUTER,TFTPSERVERIP,RANGESTART,RANGEEND,NETMASKIP,DOMAINNAME,WINXPPRODUCTKEY,W2K3PRODUCTKEY,WININSTALLIP等变量改成你实际的值; 各个变量说明如下: LOCALIP:本地服务器的IP地址,该变量仅供引用,如果你把ris linux、dhcpd、tftpd、samba等服务建立在一台服务器上,可以不用重复修改个个服务器的IP地址,而仅修改本值就能实现。 LOCALNET:dhcpd配置文件中所使用的值,用以设置本地网络。 LOCALROUTER:网关地址 TFTPSERVERIP:tftp服务器的IP地址,默认同LOCALIP RANGESTART:dhcpd配置文件中所使用的值,用以设置DHCP动态分配地址的启始地址 RANGEEND:dhcpd配置文件中所使用的值,用以设置DHCP动态分配地址的结束地址 NETMASKIP:网络的子网掩码 DOMAINNAME:缺省域名(不是必需) WINXPPRODUCTKEY:Windows XP的安装序列号 W2K3PRODUCTKEY:Windows 2003的安装序列号 WININSTALL:samba服务器的IP地址,用于提供windows安装文件,默认同LOCALIP 5. 运行install_first命令 ./install_first 运行该命令将安装所有服务包括DHCP服务,如果网络中已经有dhcp服务器请勿使用 ./install_first -nodhcp 运行该命令将不自动启用DHCP服务,但服务仍会被安装,你可以参照生成的dhcpd.conf来配置你自己已有的dhcp服务器 6. 运行install_winxp命令,配置Windows XP,供网络安装 ./install_winxp 7. 运行install_w2k3命令,配置Windows 2003,供网络安装 ./install_w2k3 8. 运行start_rislinux命令,启动RIS服务 ./start_rislinux 此时服务端的配置全部完成,客户端只要设置从网卡启动,然后输入“winxp”或“w2k3”(不含引号)即可进行Windows XP或Windows 2003的网络安装。 三、 卸载服务 可以运行uninstall命令进行卸载,但请谨慎使用。 测试安装win2k3_64bit未成功,有时间研究一下原因。 ris-autoinst开源项目 http://code.google.com/p/ris-autoinst/ 本文转自pandazhai 51CTO博客,原文链接:http://blog.51cto.com/dreamway/1045592
Linux 下vsftp的搭建与各种配置 1. 通过rpm –qa | grep vsftp 检查软件包安装情况 2. Vsftp.conf配置参数 a) 匿名用户 i. Anonymous_enable=YES 开启匿名 ii. Anon_umask=022 权限反码 iii. Anon_root=/var/ftp 设置默认访问FTP目录 iv. Anon_upload_enable=YES 文件上传 v. Anon_mkdir_write_enable=YES 写入权限 vi. Anon_other_write_enable=YES 删除改名等其他权限 vii. Anon_max_rate_0 最大传输速率(0为不限制,单位为字节) b) 本地用户 i. Local_enable=YES 开启本地用户 ii. Local_umask=022 本地上传文件权限反码 iii. Local_root=/var/ftp FTP根目录 iv. Chroot_local-user=YES 将本地用户禁锢在宿主目录中 v. Local_max_rate=0 限制本地用户传输速率 c) 全局配置 i. Listen=YES 是否以独立运行的方式监听服务 ii. Listen_port=21 设置监听FTP的端口号 iii. Write_enable=YES 开启写入权限 iv. Download_enable=YES 下载权限 v. Dirmessage_enable=YES 切入目录后显示.message文件 vi. Xferlog_enable=YES 启用xferlog日志 vii. Xferlog_std_format=YES 启用标准xferlog日志格式 viii. Connect_from_port_20=YES 允许服务器主动模式 ix. Pasv_enable=YES 允许被动模式连接 x. Pasv_max_port=24600 设置被动模式最大端口号 xi. Pasv_min_port=24500 设置被动模式最小端口号 xii. Pam_service_name=vsftpd 设置用户认证的PAMwenjian位置(/etc/pam.d目录下) xiii. Userlist_enable=YES 启用user_list用户列表 xiv. Userlist_deny=YES 禁止user list用户列表 xv. Max_clients=0 单IP的并发数限制 xvi. Tcp_wrappers=YES 是否启用tcp_wrappers主机访问控制 3. 匿名FTP的建立 a) 修改共享目录的属主和权限 b) 修改vsftpd.conf配置文件,开放匿名用户访问,上传许可。 C) 启动服务 本地用户FTP 1. 准备测试用户 a) 2. 修改vsftpd.conf a) 3. 重新启动服务 a) 建立基于虚拟用户的vsftpd服务 1. 安装vsftpd虚拟用户数据库使用berkeley DB格式的数据文件。 a) 2. 建立文本格式的用户密码列表, 奇数行位用户名,偶数行为密码 a) b) 3. 使用db_load工具转化 a) 4. 建立FTPfangwen的根目录及虚拟用户对应的系统账号,并修改权限,并建立测试文件 a) 5. 建立PAM认证文件 a) b) c) 6. 修改vsftpd.conf配置文件,添加虚拟用户支持 a) b) 7. 为不同的虚拟用户创建独立的配置文件 a) b) c) d) 8. 重新启动服务 本文转自 郑伟 51CTO博客,原文链接:http://blog.51cto.com/zhengweiit/371833
初识英雄 LDAP (轻量级目录访问协议 Lightweight Directory Access Protocol ) DS : Directory,Linux 下的目录服务 (Directory Service) 目录服务,包括Linux下的DS和Windows下的AD;最基本的功能类似于一个保存用户信息的数据库服务,其主要特点为:1.存放的数据小;2.对数据库的操作多读少写。 PS:在多读少写的情况下,一般用Raid 1 和 Raid 5 做磁盘阵列,适合多读操作。 小试牛刀 PS:最初探索DS的时候,对目录服务的相关设定十分模糊,希望下述能帮到大家理解。 1)服务中存储很多entry(条目),数据就是由多个entry组成; 2)每个entry中又包含很多attribute(属性),属性可以是phone number,address等等; 3)这些attribute又属于一个或多个object class(类)(在每个object class定义了每个attribute的规则) 奇光异彩 使用目录的案例: Gavin公司的邮件服务器使用Linux平台下的Sendmail,客户端使用Windows平台下的Outlook。 申请账号成为administrator的一大难题,Sendmail的用户信息无法与Outlook进行同步,需要administrator手动添加,但是同步工作量就变的很大。 解决方法:使用DS or AD 统一管理账号。 RE:跨平台的 Mail 服务账号同步。 Gavin公司对于员工的服务较多,包括Web、Mail等等,每个用户必须有每个服务的账号。 RE:通过DS 集中管理所有应用的账号信息。 回到过去 LDAP(轻量级目录访问协议) LDAP的父协议,可以说是前身,DAP(目录访问协议) 为什么LDAP会替代了DAP呢,或者说DAP不成熟的原因呢? 1. 复杂; 2. 效率低; 3. 对系统性能要求高。 这三点结论说明了一个问题,当时的作者希望创建一个完善的目录访问协议,通过这个协议,解决全世界的问题。这显然是不现实的。不说当时计算机服务的发展情况,就发展速度也是飞跃式的,所以想通过一个DAP解决所有问题是不现实的。 而LDAP,可以说是DAP的一部分,一个子集。所以,它所做的事情也是一个子集,所以好实现的多了。这种思想也算是跟上时代的步伐了,一个超市的老板不可能进所有品种的货物,先把好卖的集中起来展现在柜台才是上上之策。 一代新人胜旧人 LDAP相对于DAP的优势 1. 使用TCP代替OSI 7层 2. 更简单的协议设计,只有9个基本操作。 3. 使用X.500的子编码策略 4. 数据以文本形式存在 之后的演变,LDAP的服务 ldapd也被slapd所替代,也进化了一些性能: 1. 加密; 2. 提升性能; 3. 减少复杂性。 本文转自 郑伟 51CTO博客,原文链接:http://blog.51cto.com/zhengweiit/843567
JDK线程池:Executors.newFixedThreadPool , Executors.newSingleThreadExecutor,由一个ThreadFactory来创建新的线程,默认情况下为Executors.defaultThreadFactory(),ThreadFactory接口: public interface ThreadFactory { Thread newThread(Runnable r); } 我们可以采用自定义的ThreadFactory工厂,增加对线程创建与销毁等更多的控制, 一个简单的例子,跟踪线程的创建与销毁: package org.guojje.threadpool; import java.util.concurrent.atomic.AtomicInteger; public class WorkThread extends Thread { private Runnable target; private AtomicInteger counter; public WorkThread(Runnable target, AtomicInteger counter) { this.target = target; this.counter = counter; } @Override public void run() { try { target.run(); } finally { int c = counter.getAndDecrement(); System.out.println("terminate no " + c + " Threads"); } } } package org.guojje.threadpool; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.ThreadFactory; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; public class MyThread implements Runnable { public static void main(String[] args) { ExecutorService ctp = Executors.newCachedThreadPool(new ThreadFactory() { private AtomicInteger count = new AtomicInteger(); public Thread newThread(Runnable r) { int c = count.incrementAndGet(); System.out.println("create no " + c + " Threads"); return new WorkThread(r,count); } }); ctp.execute(new MyThread()); ctp.execute(new MyThread()); ctp.execute(new MyThread()); ctp.execute(new MyThread()); ctp.execute(new MyThread()); ctp.execute(new MyThread()); ctp.shutdown(); try { ctp.awaitTermination(1200, TimeUnit.SECONDS); } catch (InterruptedException e) { e.printStackTrace(); } } public void run(){ System.out.println("complete a task!!!"); } } 可以看到在执行这个过程中,共创建过几个线程。 本文转自 anranran 51CTO博客,原文链接:http://blog.51cto.com/guojuanjun/650981
最近工作特别忙,现在才稍有点时间,准备探测一下weblogic的classloader。classloader的原理google上铺天盖地,这里就不再提及了。 首先采用两个用例测试一下基本的web应与EJB应用的classloader层次结构。测试的源代码提供在附件中了: 1. web应用,包括两个同内容不同名的JSP和两个同内容不同名的Servlet. JspLoader.jsp, jspLoader2.jsp, ServletLoader, ServletLoader2. 2. EJB应用 包括一个简单的EJB3.0 bean, LoaderBean和客户端EjbClient. 测试结果: JSPLoader.Jsp: Level1: sun.misc.Launcher$ExtClassLoader@18991b Level2: sun.misc.Launcher$AppClassLoader@18ad61 Level3: weblogic.utils.classloaders.GenericClassLoader@a175d5 finder: weblogic.utils.classloaders.CodeGenClassFinder@27c1685 annotation: Level4: weblogic.utils.classloaders.FilteringClassLoader@6c10df finder: weblogic.utils.classloaders.CodeGenClassFinder@6c1153 annotation: Level5: weblogic.utils.classloaders.GenericClassLoader@6c1169 finder: weblogic.utils.classloaders.CodeGenClassFinder@6c11e2 annotation: TestClassLoader@ Level6: weblogic.utils.classloaders.ChangeAwareClassLoader@7f4e75 finder: weblogic.utils.classloaders.CodeGenClassFinder@7f4eea annotation: TestClassLoader@TestClassLoader.war Level7: weblogic.servlet.jsp.TagFileClassLoader@816eac finder: weblogic.utils.classloaders.CodeGenClassFinder@816f22 annotation: Level8: weblogic.servlet.jsp.JspClassLoader@1150af3 finder: weblogic.utils.classloaders.CodeGenClassFinder@1150b67 annotation: SystemClassLoader: sun.misc.Launcher$AppClassLoader@18ad61 JSPLoader2.Jsp: Level1: sun.misc.Launcher$ExtClassLoader@18991b Level2: sun.misc.Launcher$AppClassLoader@18ad61 Level3: weblogic.utils.classloaders.GenericClassLoader@a175d5 finder: weblogic.utils.classloaders.CodeGenClassFinder@27c1685 annotation: Level4: weblogic.utils.classloaders.FilteringClassLoader@6c10df finder: weblogic.utils.classloaders.CodeGenClassFinder@6c1153 annotation: Level5: weblogic.utils.classloaders.GenericClassLoader@6c1169 finder: weblogic.utils.classloaders.CodeGenClassFinder@6c11e2 annotation: TestClassLoader@ Level6: weblogic.utils.classloaders.ChangeAwareClassLoader@7f4e75 finder: weblogic.utils.classloaders.CodeGenClassFinder@7f4eea annotation: TestClassLoader@TestClassLoader.war Level7: weblogic.servlet.jsp.TagFileClassLoader@816eac finder: weblogic.utils.classloaders.CodeGenClassFinder@816f22 annotation: Level8: weblogic.servlet.jsp.JspClassLoader@1150af3 finder: weblogic.utils.classloaders.CodeGenClassFinder@1150b67 annotation: SystemClassLoader: sun.misc.Launcher$AppClassLoader@18ad61 ServletLoader: Level1: sun.misc.Launcher$ExtClassLoader@18991b Level2: sun.misc.Launcher$AppClassLoader@18ad61 Level3: weblogic.utils.classloaders.GenericClassLoader@a175d5 finder: weblogic.utils.classloaders.CodeGenClassFinder@27c1685 annotation: Level4: weblogic.utils.classloaders.FilteringClassLoader@6c10df finder: weblogic.utils.classloaders.CodeGenClassFinder@6c1153 annotation: Level5: weblogic.utils.classloaders.GenericClassLoader@6c1169 finder: weblogic.utils.classloaders.CodeGenClassFinder@6c11e2 annotation: TestClassLoader@ Level6: weblogic.utils.classloaders.ChangeAwareClassLoader@7f4e75 finder: weblogic.utils.classloaders.CodeGenClassFinder@7f4eea annotation: TestClassLoader@TestClassLoader.war SystemClassLoader: sun.misc.Launcher$AppClassLoader@18ad61 ServletLoader2: Level1: sun.misc.Launcher$ExtClassLoader@18991b Level2: sun.misc.Launcher$AppClassLoader@18ad61 Level3: weblogic.utils.classloaders.GenericClassLoader@a175d5 finder: weblogic.utils.classloaders.CodeGenClassFinder@27c1685 annotation: Level4: weblogic.utils.classloaders.FilteringClassLoader@6c10df finder: weblogic.utils.classloaders.CodeGenClassFinder@6c1153 annotation: Level5: weblogic.utils.classloaders.GenericClassLoader@6c1169 finder: weblogic.utils.classloaders.CodeGenClassFinder@6c11e2 annotation: TestClassLoader@ Level6: weblogic.utils.classloaders.ChangeAwareClassLoader@7f4e75 finder: weblogic.utils.classloaders.CodeGenClassFinder@7f4eea annotation: TestClassLoader@TestClassLoader.war SystemClassLoader: sun.misc.Launcher$AppClassLoader@18ad61 EJB: Level1: sun.misc.Launcher$ExtClassLoader@18991b Level2: sun.misc.Launcher$AppClassLoader@18ad61 Level3: weblogic.utils.classloaders.GenericClassLoader@a175d5 finder: weblogic.utils.classloaders.CodeGenClassFinder@27c1685 annotation: Level4: weblogic.utils.classloaders.FilteringClassLoader@1e8de86 finder: weblogic.utils.classloaders.CodeGenClassFinder@1e8defa annotation: Level5: weblogic.utils.classloaders.GenericClassLoader@1e8df10 finder: weblogic.utils.classloaders.CodeGenClassFinder@1e8df89 annotation: TestEJB3Loader@ SystemClassLoader: sun.misc.Launcher$AppClassLoader@18ad61 从上面的结果首先以下结论: 同一Web应用的JSP或Servlet,其classloader的前六层是一样的(严格的说是7层,因为bootstrapClassLoader没输出,原因这里也不提了)。 对于JSP页面多了两层Classloader,TagFileClassLoader 和JspClassLoader,从上面结果可以看每个JSP文件对应一个JspClassLoader,而整个web应用的JSP页面共用一个TagFileClassLoader。 再看EJB,classloader的前三层与web应用的前三层是一样的,基本以为GenericClassLoader是用来加载weblogic的产品内部的相关类,前两层用来加载JDK的类,具体情况以后再做论述。 weblogic11g p3也是就10.3.4(oracle把weblogic的这个版本号搞得人晕头转向,后附一个版本对照表)添加了一个类分析工具Classloader Analysis Tool,以web应用的方式法提供。 在开发模式下可以用http://host:port/wls-cat来访问。可以帮助解决类冲突或研究weblogic的classloader结构,这里有两个文章可以参考。 http://blog.eisele.net/2011/01/using-new-weblogic-classloader-analysis.html https://blogs.oracle.com/jeffwest/entry/weblogic_1034_classloader_analysis_tool 版本对照表 Release GA Date Pre_Sup_Ends Ext_Sup_Ends Sus_Sup_Ends WebLogic Server 12.1.x (12c) - Dec 2011 Dec 2016 Dec 2019 Indefinite WebLogic Server 11gR1 PS3 (10.3.4) - 15 Jan 2011 Jun 2014 Jun 2017 Indefinite WebLogic Server 11gR1 PS2 (10.3.3) - April 2010 Jun 2014 Jun 2017 Indefinite WebLogic Server 11gR1 PS1 (10.3.2) - Nov 2009 Jun 2014 Jun 2017 Indefinite WebLogic Server 11g (10.3.1) - Jul 2009 Mar 2013 Mar 2015 Indefinite WebLogic Server 10.3 - Aug 2008 Jan 2014 Jan 2017 Indefinite WebLogic Server 10.0 - Mar 2007 Mar 2013 Mar 2015 Indefinite WebLogic Server 9.x - Nov 2006 Nov 2011 Nov 2013 Indefinite 本文转自 anranran 51CTO博客,原文链接:http://blog.51cto.com/guojuanjun/1024159
在DHTML和JAVASCRIPT编程中,都会用到大量STYLE或属性来设置页面效果和元素特性的。比如非常常用的ALIGN、SIZE、WIDTH、FONT-COLOR等,不过其中在CSS和DHTML属性的不同可能会导致一些设置出错或无效的时候。 1、 cursor:pointer!important;cursor:hand; 在TD等HTML元素中作为STYLE属性赋值可支持多种浏览器平台,但在CSS中不被支持。在属性中可以设置CURSOR多种取值,在CSS中也不被支持。 2、ALIGN在DHTML元素中用的比比皆是,且被大多数平台支持(DOM技术),但在CSS中只有TEXT-ALIGN来代替。即便是HR元素,在CSS中也须用TEXT-ALIGN来设置对齐(至少从多浏览器支持角度来说,因为MS IE会做很多不标准用法的兼容和容错,不予作为标准来考虑)。 3、在CSS中对属性取值必须不用双引号括起,否则会引起浏览器平台兼容问题(MS IE又支持了这种非标准用法)。在DHTML元素的属性取值时,双引号是可选的,当然是在不会引起岐义的前提 本文转自 dannyy1026 51CTO博客,原文链接: http://blog.51cto.com/dannyyuan/41208
闭包这个概念看上去很深奥,这个词在离散数学里面的意思确实比较难于理解。在这里,我们先可以把闭包理解成是一种匿名函数或者匿名类。 1. 什么是闭包? 什么是闭包?一种正式的解释是:所谓闭包,指的是一种拥有很多变量并且绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是这个表达式的一部分。 相信很多人都不会理解这个定义,因为他的学术味道太浓了——或许你喜欢从字面的语法上进行分析:首先,它是一个表达式,这个表达式绑定了很多变量以及这些变量的环境。不过这并没有什么意义,这依然不会告诉我们什么是闭包。 那么,来看一个例子: function add(a) { return function(b) { return a + b; }; } var func = add(10); alert(func(20)); 我想经过了前面有关函数的描述,这个例子应该很清楚的理解。JavaScript里面的函数就是对象,他可以做对象能做的一切事情——我们首先定义了一个函数add,它接受一个参数,这个函数返回一个匿名函数,这个匿名函数也接受一个参数,并且会返回这个参数同外部函数的那个参数的和。因此在我们使用的时候,我们将add返回的匿名函数赋值给func,然后调用func,就返回了这两个数的和。 当我们创建一个这样的函数,这个函数内部的一个变量能够在函数外面被引用时,我们就称创建了一个闭包。仔细的品味一下:这就是那个闭包的定义。 看看我们的代码:首先,它有一个内部变量,就是那个匿名函数;其次,这个函数将匿名函数返回了出去,以便外面的变量可以引用到内部定义的变量。 2. 闭包的作用 闭包有什么用呢?或许现在还看不出来,那么看看这段代码: function inc(a) { var i = 0; return function() { return i; }; } var num = inc(); alert(num()); 本来,这个变量 i 在函数外面是访问不到的,因为它是 var 定义的,一旦跳出作用域,这个变量就被垃圾回收了,但是,由于我们使用了闭包,在外面是能够访问到这个变量的,因此它并不被垃圾回收! 如果还是不明白闭包的作用,那么看一段应该很熟悉的代码: function Person() { var id; this.getId = function() { return id; } this.setId = function(newId) { id = newId; } } var p = new Person(); p.setId(1000); alert(p.getId()); // 1000 alert(p.id); // undefined 我们定义一个类Person,它有一个id属性。现在这个属性的行为很像是私有变量——只能通过 setter 和 getter 函数访问到。没错,这就是闭包的一个用途:制造类的私有变量! 闭包还有一个作用:在内存中维护一个变量,不让垃圾回收器回收这个变量。这里的例子就不再举出了。 这里我们只是简单的说了JavaScript的闭包的概念,并没有涉及闭包的内存模型等等之类。这是一个相当重要的概念,Java社区中的部分成员一直对闭包梦寐以求,C#也已经在最新版本中添加了闭包的概念,只不过在那里称为lambda表达式。 本文转自 FinderCheng 51CTO博客,原文链接: http://blog.51cto.com/devbean/174927
所谓 IO 其实不过是与其他设备之间的数据交互。在 Linux 上这个概念或许会更加清楚一些。Linux 把所有设备都看作是一种文件,因此所有的 IO 都归结到对文件的数据交互。同样,与其他进程之间也存在着数据交互,这就是进程间交互。 为什么需要进程间交互呢?Qt 虽然是一个很庞大的库,但是也不能面面俱到。每个需求都提供一种解决方案是不现实的。比如操作系统提供了查看当前文件夹下所有文件的命令(Windows 下是 dir, Linux 下是 ls),那么 Qt 就可以通过调用这个命令获取其中的信息。当然这不是一个很恰当的例子,因为 Qt 同样提供了相同的操作。不过,如果你使用版本控制系统,比如 SVN,然后你希望通过 SVN 的版本号生成自己系统的 build number,那么就不得不调用 svn 命令获取当前仓库的版本号。这些操作都涉及到进程间交互。 Qt 使用 QProcess 类完成进程间交互。我们从例子开始看起。由于比较简单,所以没有把 main() 函数贴上来,大家顺手写下就好的啦! mainwindow.h #ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QtGui> class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(QWidget *parent = 0); ~MainWindow(); private slots: void openProcess(); private: QProcess *p; }; #endif // MAINWINDOW_H mainwindow.cpp #include "mainwindow.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { p = new QProcess(this); QPushButton *bt = new QPushButton("execute notepad", this); connect(bt, SIGNAL(clicked()), this, SLOT(openProcess())); } MainWindow::~MainWindow() { } void MainWindow::openProcess() { p->start("notepad.exe"); } 这个窗口很简单,只有一个按钮,当你点击按钮之后,程序会调用 Windows 的记事本。这里我们使用的是 p->start("notepad.exe"); 语句。QProcess::start() 接受两个参数,第一个是要执行的命令或者程序,这里就是 notepad.exe;第二个是一个 QStringList 类型的数据,也就是需要传递给这个程序的运行参数。注意,这个程序是需要能够由系统找到的,一般是完全路径。但是这里为什么只有 notepad.exe 呢?因为这个程序实际是放置在 Windows 系统文件夹下,是已经添加到了系统路径之中,因此不需要再添加本身的路径。 下面我们再看一个更复杂的例子,调用一个系统命令,这里我使用的是 Windows,因此需要调用 dir;如果你是在 Linux 进行编译,就需要改成 ls 了。 mainwindow.h #ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QtGui> class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(QWidget *parent = 0); ~MainWindow(); private slots: void openProcess(); void readResult(int exitCode); private: QProcess *p; }; #endif // MAINWINDOW_H mainwindow.cpp #include "mainwindow.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { p = new QProcess(this); QPushButton *bt = new QPushButton("execute notepad", this); connect(bt, SIGNAL(clicked()), this, SLOT(openProcess())); } MainWindow::~MainWindow() { } void MainWindow::openProcess() { p->start("cmd.exe", QStringList() << "/c" << "dir"); connect(p, SIGNAL(finished(int)), this, SLOT(readResult(int))); } void MainWindow::readResult(int exitCode) { if(exitCode == 0) { QTextCodec* gbkCodec = QTextCodec::codecForName("GBK"); QString result = gbkCodec->toUnicode(p->readAll()); QMessageBox::information(this, "dir", result); } } 我们仅增加了一个 slot 函数。在按钮点击的 slot 中,我们通过 QProcess::start() 函数运行了指令 cmd.exe /c dir 这里是说,打开系统的 cmd 程序,然后运行 dir 指令。如果有对参数 /c 有疑问,只好去查阅 Windows 的相关手册了哦,这已经不是 Qt 的问题了。然后我们 process 的 finished() 信号连接到新增加的 slot 上面。这个 signal 有一个参数 int。我们知道,对于 C/C++ 程序而言,main() 函数总是返回一个 int,也就是退出代码,用于指示程序是否正常退出。这里的 int 参数就是这个退出代码。在 slot 中,我们检查退出代码是否是0,一般而言,如果退出代码为0,说明是正常退出。然后把结果显示在 QMessageBox 中。怎么做到的呢?原来,QProcess::readAll() 函数可以读出程序输出内容。我们使用这个函数将所有的输出获取之后,由于它的返回结果是 QByteArray 类型,所以再转换成 QString 显示出来。另外注意一点,中文本 Windows 使用的是 GBK 编码,而 Qt 使用的是 Unicode 编码,因此需要做一下转换,否则是会出现乱码的,大家可以尝试一下。 好了,进程间交互就说这么说,通过查看文档你可以找到如何用 QProcess 实现进程过程的监听,或者是令Qt 程序等待这个进程结束后再继续执行的函数。 本文转自 FinderCheng 51CTO博客,原文链接: http://blog.51cto.com/devbean/305116
第一次在Struts1.2.x中使用数据源,谁知在Tomcat6启动时发生了错误,百度一搜,发现有许多网友也有这样的疑问,好不容易找到一位网友给的解决方法! 先把问题描述清楚: 1. Tomcat启动,当识别Struts1.2.x并使用了数据源的项目时,会有以下错误: 严重: Initializing application data source datasourcejava.lang.ClassNotFoundException: org.apache.commons.dbcp.BasicDataSource at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1358) ...... 我记得Tomcat已经自带dbcp包,但是用winRar打开tomcat-dbcp.jar,发现tomcat-dbcp.jar的内部结构:org.apache.tomcat.dbcp.dbcp.BasicDataSource! Tomcat6的doc也提到 JNDI Datasource HOW-TO DBCP uses the Jakarta-Commons Database Connection Pool. It relies on number of Jakarta-Commons components: Jakarta-Commons DBCP Jakarta-Commons Collections Jakarta-Commons Pool These libraries are located in a single JAR at $CATALINA_HOME/lib/tomcat-dbcp.jar. However, only the classes needed for connection pooling have been included, and the packages have been renamed to avoid interfering with applications. 解决办法: 到[url]http://www.apache.org/dist/commons/dbcp/binaries/[/url] 下载commons-dbcp-1.2.2.zip,以后可能会看到更高版本的! 把里面的commons-dbcp-1.2.2.jar放到Tomcat目录下的lib文件夹! 2. 再次启动Tomcat,又有新的错误; 严重: Unable to initialize Struts ActionServlet due to an unexpected exception or error thrown, so marking the servlet as unavailable. Most likely, this is due to an incorrect or missing library dependency.java.lang.NoClassDefFoundError: org/apache/commons/pool/impl/GenericObjectPool at java.lang.Class.getDeclaredConstructors0(Native Method) ...... 解决办法: 到[url]http://www.apache.org/dist/commons/pool/binaries/[/url] 下载commons-pool-1.3.zip,把里面的commons-pool-1.3.jar放到Tomcat目录下的lib文件夹! 这样就ok!在这里顺便提供这两个zip包的直接下载 附件:http://down.51cto.com/data/2349038 本文转自 Icansoft 51CTO博客,原文链接: http://blog.51cto.com/android/56117
本文是对网上的文章《Android开发指南-用户界面-对话框》的部分内容进行简化,并加上自己的某些理解。里面的相同内容,版权归原翻译作者所有。 显示对话框 对话框经常作为Activity的一部分来创建和显示。你通常应该从protected Dialog Activity.onCreateDialog (int id) 回调方法里创建对话框。当你使用这个回调函数时,Android系统会有效的设置这个Activity为每个对话框的所有者,从而自动管理每个对话框的状态并挂靠到Activity上。这样,每个对话框继承这个Activity的特定属性。比如,当一个对话框打开时,菜单键显示为这个Activity定义的选项菜单,音量键修改Activity使用的音频流。 注意: 如果你决定在onCreateDialog()方法之外创建一个对话框,它将不会被附着到活动上。不过,你可以通过setOwnerActivity(Activity)把它附着到一个活动上。 当你想要显示一个对话框时,调用showDialog(int id) 方法并传递一个唯一标识这个对话框的整数。 当对话框第一次被请求时,Android从你的Activity中调用onCreateDialog(int id),你应该在这里初始化这个对话框Dialog。这个回调方法被传以和showDialog(int id)相同的ID。当你创建这个对话框后,在Activity的最后返回这个对象。 在对话框被显示之前,Android还调用了可选的回调函数onPrepareDialog(int id, Dialog). 如果你想在每一次对话框被打开时改变它的任何属性,你可以定义这个方法。这个方法在每次打开对话框时被调用,而onCreateDialog(int) 仅在对话框第一次打开时被调用。如果你不定义onPrepareDialog(),那么这个对话框将保持和上次打开时一样。这个方法也被传递以对话框的ID,和在onCreateDialog()中创建的对话框对象。(个人理解是,在本Activity里第一次show某个Dialog,则先调用onCreateDialog,得到返回的Dialog对象并挂靠在Activity,保存Dialog对象的引用,然后才显示Dialog。这样子,下次再show Dialog就不用重新创建Dialog对象,而是重用旧的) 定义onCreateDialog(int) 和 onPrepareDialog(int, Dialog) 回调函数的最佳方法是使用一个switch 语句来检查传递进来的id 参数。每个case 应该检查一个唯一的对话框ID然后创建和定义相应的对话框。比如,想象一下一个游戏使用两个不同的对话框:一个用来指示这个游戏已经暂停而另一个来指示游戏结束。首先,为每个对话框定义一个常量: static final int DIALOG_PAUSED_ID = 0; static final int DIALOG_GAMEOVER_ID = 1; 然后,为每一个ID用一个switch case定义这个onCreateDialog(int) 回调函数: protected Dialog onCreateDialog(int id) { Dialog dialog; switch(id) { case DIALOG_PAUSED_ID: // do the work to define the pause Dialog break; case DIALOG_GAMEOVER_ID: // do the work to define the game over Dialog break; default: dialog = null; } return dialog; } 当是时候显示其中之一的对话框时,使用对话框ID调用showDialog(int): showDialog(DIALOG_PAUSED_ID); 消除对话框Dismissing a Dialog 当你准备关闭对话框时,你可以通过对这个对话框调用dismiss()来消除它。如果需要,你还可以从这个Activity中调用dismissDialog(int id) 方法,这实际上将为你对这个对话框调用dismiss() 方法。 如果你想使用onCreateDialog(int id) 方法来管理你对话框的状态(就如同在前面的章节讨论的那样),然后每次你的对话框消除的时候,这个对话框对象的状态将由该Activity保留。如果你决定不再需要这个对象或者清除该状态是重要的,那么你应该调用removeDialog(int id)。这将删除任何内部对象引用而且如果这个对话框正在显示,它将被消除。 使用消除侦听器Using dismiss listeners 如果你希望你的应用程序在一个对话框消亡的时候执行一些流程,那么你应该附着一个on-dismiss侦听器到对话框上。 @Override protected void onPrepareDialog(int id, Dialog dialog) { switch(id){ case PROGRESS_DIALOG: dialog.setOnDismissListener(new DialogInterface.OnDismissListener(){ @Override public void onDismiss(DialogInterface dialog) { Toast.makeText(getApplicationContext(), "dismiss listener!", Toast.LENGTH_SHORT) .show(); } }); } } 然而, 请注意对话框也可以被“取消”。这是一个表明对话框被用户显示取消的特殊情况。这将在用户按“返回”按钮时发生,或者这个对话框显示的调用cancel() (也许通过对话框上的一个“取消”按钮)。当一个对话框被取消时,这个OnDismissListener 依然会被通知到,但是如果你希望在对话框被显示取消时被通知到(而不是通常的消除方式),那么你应该通过setOnCancelListener()注册一个DialogInterface.OnCancelListener 。 目前个人学习发现,一般情况下,调用dialog.cancel()就会触发onCancelLister。而点击AlertDialog的NegativeButton (Cancel/No)是不会触发的。对于setOnCancelListener()要注意的是,这里有两个setOnCancelListener(),但返回值不同: //AlertDialog.Builder调用的 public AlertDialog.Builder setOnCancelListener (DialogInterface.OnCancelListener onCancelListener) //Dialog调用的 public void setOnCancelListener (DialogInterface.OnCancelListener listener) 警告对话框AlertDialog的使用 为了创建一个警告对话框,使用AlertDialog.Builder 子类。通过AlertDialog.Builder(Context)获取一个构造器然后使用这个类的公共方法来定义警告对话框的所有属性。当得到构造器后,通过create().方法来获取警告对话框对象。有时我是不调用create()的,而是在设置好了后直接调用show()显示AlertDialog。 增加按钮Adding buttons 这就是我一开始很想知道的究竟如何添加Yes/No,Ok/Cancel这样的按钮。原来是通过setPositiveButton(...)响应Yes/Ok的点击,setNeutralButton(...)响应中立行为的点击,setNegativeButton(...)响应No/Cancel的点击。注意,只能各自设置一个按钮来响应点击事件。 AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setMessage("Are you sure you want to exit?") .setCancelable(false) .setPositiveButton("Yes", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { MyActivity.this.finish(); } }) .setNegativeButton("No", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { dialog.cancel(); } }); AlertDialog alert = builder.create(); 首先,为这个对话框添加一个消息setMessage(CharSequence)。然后,开始函数链并设置该对话框为不能取消not cancelable (因此用户不能使用返回按钮关闭这个对话框)。对每个按钮,使用任一set...Button() 方法,比如setPositiveButton(),该方法接受按钮名称以及一个定义用户选中按钮后所采取动作的DialogInterface.OnClickListener。 增加一个列表Adding a list final CharSequence[] items = {"Red", "Green", "Blue"}; AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setTitle("Pick a color"); builder.setItems(items, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int item) { Toast.makeText(getApplicationContext(), items[item], Toast.LENGTH_SHORT).show(); } }); AlertDialog alert = builder.create(); 首先,用setTitle(CharSequence)方法给对话框添加一个标题。然后,添加用setItems()添加一个可选项列表,该列表接受一组显示的items和一个DialogInterface.OnClickListener 来定义用户选中按钮后所采取动作。 增加复选框和单选按钮 要在对话框里创建一个多选项列表(checkboxes)或者单选项(radio buttons),可分别调用setMultiChoiceItems() 和setSingleChoiceItems() 方法。如果你在onCreateDialog()回调函数中创建这些可选列表,Android会帮你管理列表状态。只要这个活动是激活的,对话框会记住之前选中的items,但如果用户退出这个活动,用户选择将丢失。 注意: 为了在用户离开或暂停这个活动的时候能够保存选择,你必须通过活动生命期Activity Lifecycle来恰当的保存和恢复设置。为了永久保存选项,即使活动进程被完全终止,你需要使用数据存储Data Storage技术。 final CharSequence[] items = {"Red", "Green", "Blue"}; AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setTitle("Pick a color"); builder.setSingleChoiceItems(items, -1, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int item) { Toast.makeText(getApplicationContext(), items[item], Toast.LENGTH_SHORT).show(); } }); AlertDialog alert = builder.create(); setSingleChoiceItems() 的第二个参数是一个checkedItem整型数值,指示了基于0的缺省选择项的位置。“-1”代表不会有默认选择项。 进度对话框Progress Dialog的使用 ProgressDialog是AlertDialog类的一个扩展,可以为一个未定义进度的任务显示一个旋转轮形状的进度动画,或者为一个指定进度的任务显示一个进度条。 可以简单地通过调用ProgressDialog.show()方法来显示一个进度对话框,而通过onCreateDialog(int)回调管理这个对话框是可选的,如下所示: ProgressDialog.show(this, // context "", // title "Loading. Please wait...", // message true); //进度是否是不确定的,这只和创建进度条有关 进度对话框的缺省类型是一个旋转轮,运行看到的是以下效果: 由于ProgressDialog是AlertDialog的扩展类,所以ProgressDialog也能设置按钮,比如一个取消下载的按钮。不过要注意的是,和前面的AlertDialog.Builder不同,ProgressDialog是调用AlertDialog的setButton,setButton2,setButton3函数,这些函数没有明确哪个是正面/中立/负面的,由我们决定。 显示进度条Showing a progress bar 而选择动画进度条显示进度: 1. 用类构造器初始化进度对话框,ProgressDialog(Context)。 2. 用setProgressStyle(int)方法设置进度风格为"STYLE_HORIZONTAL"以及设置其它属性,比如消息。 创建ProgressDialog大概是这样的: ProgressDialog progressDialog = new ProgressDialog(getApplicationContext()); progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); progressDialog.setIcon(R.drawable.alert_dialog_icon); progressDialog.setMessage("Loading..."); progressDialog.setCancelable(false); 3. 当你准备显示这个对话框时,调用show()或者从onCreateDialog(int)回调中返回ProgressDialog。 4. 你可以通过调用setProgress(int)设置当前进度百分比或者调用incrementProgressBy(int)方法增加进度值。 官方文档提供了如何在另一线程来跟踪进程进度,让进度值变化。对此可以参考http://androidappdocs.appspot.com/guide/topics/ui/dialogs.html里面的代码。也可以查看后面的文章《有关Android线程的学习》里面的例子,看看如何使用Handler, Message机制! 创建自定义对话框Creating a Custom Dialog 创建自定义对话框,首先要创建一个Layout xml 文件,在此不啰嗦了。然后加载Layout有两种方法,也是非常熟悉的那两种方法: 1. setContentView(int resources id) 2. 利用LayoutInflater加载 官方还提示我们,一般使用Dialog类来创建对话框,是需要setTitle的,不设置的话,标题占用的空间保持为空,但仍然可见。而不想要那个标题,那应该使用警告对话框AlertDialog来创建自定义对话框。然而,因为警告对话框可以很简单的通过AlertDialog.Builder 类来创建,你并不需要访问上面使用的setContentView(int) 方法。相反,你必须使用setView(View),则需要使用LayoutInflater来加载Layout得到View。 具体代码参考http://androidappdocs.appspot.com/guide/topics/ui/dialogs.html 本文转自 Icansoft 51CTO博客,原文链接: http://blog.51cto.com/android/333769
ListActivity ListActivity是一个专门显示ListView的Activity类,它内置了ListView对象,只要我们设置了数据源,就会自动地显示出来。 使用custom view for screen layout 虽然ListActivity内置了ListView对象,但我们依然可以使用custom view,通过在onCreate()里面调用setContentView(resources id)。 不过要注意的是,在自定义的Layout里面,要设置ListView对象的id为"@android:id/list";在Java代码里使用android.R.id.list。 下面的例子,通过添加一个id为android:empty的TextView,当ListView里面没有data的时候,就会显示"No data"。 自定义的View (listview.xml): <?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <ListView android:id="@id/android:list" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="1" /> <TextView android:id="@id/android:empty" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="No data" android:textColor="#ff0000" /></LinearLayout> 加载Layout: @Overridepublic void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.listview); //没有设置data source } Row Layout 官方提供了多种ListItem的Layout (R.layout),以下是较为常用的,更多的请查看API DOC的R.layout http://androidappdocs.appspot.com/reference/android/R.layout.html: android.R.layout.simple_list_item_1 一行text android.R.layout.simple_list_item_2 一行title,一行text android.R.layout.simple_list_item_single_choice 单选按钮 android.R.layout.simple_list_item_multiple_choice 多选按钮 android.R.layout.simple_list_item_checked checkbox 我们可以自定义自己的Layout (list_item.xml): <?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="fill_parent"> <ImageView android:id="@+id/icon" android:layout_width="48dip" android:layout_height="48dip" /> <TextView android:id="@+id/text" android:layout_gravity="center_vertical" android:layout_width="0dip" android:layout_weight="1" android:layout_height="wrap_content" /></LinearLayout> 使用时,以R.layout.list_item引用就行了。可以参考http://androidappdocs.appspot.com/resources/tutorials/views/hello-listview.html。 绑定数据 通过调用SetListAdapter(ListAdapter adapter)就可实现。我们可以implements ListAdapter来自定义自己的数据源。API内置了几个implements ListAdapter的Adapter:BaseAdapter,SimpleAdapter (以Map的形式存储静态数据),SimpleCursorAdapter (用于游标查询的结果)等等。通常我们更多地extends BaseAdapter来编写自己的Adapter类,因为BaseAdapter类是其他Apdater类的基类。扩展BaseAdapter类一般都需要重写以下方法: int getCount() 获取当前Adapter的Items数目 Object getItem(int position) 获取相应position的Item long getItemId(int position) 获取相应position的Item在List中的row id View getView(int position, View convertView, ViewGroup parent) 获取在指定position所要显示的data的View 详细内容可以查看BaseAdapter类的继承android.widget.Adapter的方法,有时也需要重写ListAdapter的boolean isEnabled(int position)来实现某些效果。 接下来看看几个绑定数据的例子: 1. 使用ArrayAdapter public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //参考ArrayAdapter的构造函数 setListAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, mStrings)); //在ListView上输入字母,就会自动筛选出以此内容开头的Item getListView().setTextFilterEnabled(true); }private String[] mStrings = {"A", "Android", "机器人", "Google"}; 2. 使用SimpleCursorAdapter 这是Sample里面List3例子,通过读取通讯录android.provider.Contacts.Phones的资料,显示出来。 protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Get a cursor with all phones Cursor c = getContentResolver().query(Phones.CONTENT_URI, null, null, null, null); startManagingCursor(c); // Map Cursor columns to views defined in simple_list_item_2.xml ListAdapter adapter = new SimpleCursorAdapter(this, android.R.layout.simple_list_item_2, c, new String[] { Phones.NAME, Phones.NUMBER }, new int[] { android.R.id.text1, android.R.id.text2 }); setListAdapter(adapter); } 3. ListItem为单选按钮 public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //参考ArrayAdapter的构造函数 setListAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_single_choice, mStrings)); final ListView listView = getListView(); listView.setItemsCanFocus(false); listView.setChoiceMode(ListView.CHOICE_MODE_SINGLE); //设置单选模式 }private String[] mStrings = {"A", "Android", "机器人", "Google"}; 4. ListItem为多选按钮 把例子3的设置为android.R.layout.simple_list_item_multiple_choice以及选择模式ListView.CHOICE_MODE_MULTIPLE。 更多的例子可以参考官方的Sample,在此列出相关List的示例说明: List1 - 使用ArrayAdapter并setTextFilterEnabled(true) List2 - 使用SimpleCursorAdapter读取通讯录People.NAME List3 - 使用SimpleCursorAdapter读取通讯录Phones,两行显示Item List4 - 使用自定义Adapter以及自定义ItemView List5 - 带有separator的ListView,通过自定义Adapter,重写boolean isEnabled(int position) List6 - 使用自定义Adapter以及自定义ItemView,可伸展隐藏内容 List7 - 使用SimpleCursorAdapter读取数据 List8 - 展现使用setEmptyView效果 List9 - 涉及OnScrollListener List10 - ListItem为单选按钮 List11 - ListItem为多选按钮 List12 - 可以动态添加ListItem List13 - 如何加快操作显示,during scrolls or flings的时候 List14 - 如何编写高效的List Adapter 其中List14,官方告诉我们: To work efficiently the adapter implemented here uses two techniques: * - It reuses the convertView passed to getView() to avoid inflating View when it is not necessary * - It uses the ViewHolder pattern to avoid calling findViewById() when it is not necessary 还告诉了我们ViewHolder类的作用: * The ViewHolder pattern consists in storing a data structure in the tag of the view returned by * getView(). This data structures contains references to the views we want to bind data to, thus * avoiding calls to findViewById() every time getView() is invoked. 另外在以上的例子里面了解到,使用自定义Adapter,当数据发生变化后需要调用notifyDataSetChanged()来刷新ListView,但在List12的例子,使用ArrayAdapter却没有调用这方法,而随后自己写代码,在发生的异常里面了解到BaseAdapter,ArrayAdapter是会调用自己的notifyDataSetChanged()。可以查看后面的文章《有关Android线程的学习》里面的例子! ListView的事件响应 通常我们响应ListItem的点击事件:protected void onListItemClick(ListView l, View v, int position, long id) ,在此不详细讲了,理解该函数里面的参数意义就行了。 本文转自 Icansoft 51CTO博客,原文链接: http://blog.51cto.com/android/336162
本文是按照Thinking in Java的章节温习的。仅记录有注释的章节。 第一章 对象入门 Introduction to Objects 1. 面向对象的三个基本特征 2.[转]关于Java中各种修饰符与访问修饰符的说明 Java的类有个默认类型,只能被同一package的其他类访问。 第二章 一切皆对象 Everything is an Object 1. 栈和堆的区分 栈,因为本身是FILO - first in, last out. 先进后出,能够自动释放,不需要垃圾回收。而堆是内存池,保存数据比栈灵活,需要用new命令创建对象,所以垃圾回收GC是针对堆Heap。 同时因为栈的特性,所以方法/函数的变量,引用是存放在栈里,当退出作用域后则自动清理这些变量!而且栈的读取速度比堆所在的内存要快,因为堆需要定位数据,而栈不需要,所以Java代码优化--尽可能地使用stack(栈)变量,实际上就是尽量使用局部变量,把成员变量引用传递到函数方法里面的变量! 参考[Java]Stack栈和Heap堆的区别(终结篇)。 2. 成员变量的默认值和局部变量的初始化 Java和C++的其中不同之处:在Java里面,类里面的成员变量是有默认值的: 变量类型 默认值 Boolean false Char '\u0000'(null) 显示为空白 byte (byte)0 short (short)0 int 0 long 0L float 0.0f double 0.0d 而对象引用则默认值为null。 但函数方法里面的变量是不会分配默认值的,这点和C++是一致的。可以参考一下程序: public class Demo { int i; char c; String s; public void print() { //Error: 可能损失精度 //找到: double //需要: float //float f = 1.1; float f = 1.1f; int num; String ss; //Error: 可能尚未初始化变量 num //System.out.println(num); System.out.println(i); System.out.println(c); //Error: 可能尚未初始化变量 ss //if (ss == null) if (s == null) System.out.println("null"); } public static void main(String[] args) { new Demo().print(); } } 输出结果为 0 空白 null ***所以函数方法里面的变量一定要初始化。 3. float 类型的赋值 从上一个程序可以看到,当需要给float类型的变量赋值,需要加上后缀 f 来表示。 4. 参数的传递 要小心把对象传递给方法的形参时,所传递的是引用,就是说在方法能够修改原来对象里面的数据。而为了避免这个问题,则对形参加上final修饰词,使得这个形参在方法里不能修改所引用的对象的数据。 第三章 控制程序流程 Controlling Program Flow 1. Java5的for/in循环使用 2. return语句在try-catch-finally中的执行顺序 第四章 初始化和清除 Initialization & Cleanup ~ 第八章 接口和内部类 1. 关键字this, super this 表示当前类的对象。super表示当前子类的父类对象。Java里在子类中用super 调用父类构造函数时,调用函数必须放在子类构造函数的第一条语句的位置,否则编译错误。 2. Java关键字static、final使用小结 3. Java类和对象的初始化顺序 4. [Java]重载,重写以及继承,多态的区别 5. Java抽象类和接口的学习 6. Java内部类的使用小结 7. 什么是多态?为什么用多态?有什么好处? 本文转自 Icansoft 51CTO博客,原文链接: http://blog.51cto.com/android/385292
1. SQLiteDatabase 操作SQLite数据库的类。可以执行SQL语句,对数据库进行增、删、查、改的操作。也可以进行transaction的控制。很多类对数据库的操作最终都是通过SQLiteDatabase实例来调用执行的。 需要注意的是,数据库对于一个应用来说是私有的,并且在一个应用当中,数据库的名字也是惟一的。 2. SQLiteOpenHelper 创建数据库和数据库版本管理的辅助类。这是一个抽象类,所以我们一般都有一个SQLiteOpenHelper子类,需要继承实现 · void onCreate(SQLiteDatabase db) 在数据库第一次生成的时候会调用这个方法,一般我们在这个方法里边生成数据库表。 · void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) 当数据库需要升级的时候,Android系统会主动的调用这个方法。一般我们在这个方法里边删除数据表,并建立新的数据表,当然是否还需要做其他的操作,完全取决于应用的需求。 而void onOpen(SQLiteDatabase db) 则可以选择重写。同时此类还有3个synchronized方法:void close(),SQLiteDatabase getReadableDatabase(),SQLiteDatabase getWritableDatabase()。 3. Cursor 游标。要注意这是一个接口。但很多时候我不需要知道它具体是哪个子类,直接按照API Doc里面提供的方法调用就行了。通过Cursor 我们可以对从数据库查询出来的结果集进行随机的读写访问。对于数据库的查询结果,一般是由子类SQLiteCursor返回的。 4. ContentProvider 因为在Android系统里面,数据库是私有的。一般情况下外部应用程序是没有权限读取其他应用程序的数据。如果你想公开你自己的数据,你有两个选择:你可以创建你自己的内容提供器(一个ContentProvider子类)或者你可以给已有的提供器添加数据-如果存在一个控制同样类型数据的内容提供器且你拥有写的权限。而外界根本看不到,也不用看到这个应用暴露的数据在应用当中是如何存储的,或者是用数据库存储还是用文件存储,还是通过网上获得,这些一切都不重要,重要的是外界可以通过这一套标准及统一的接口和程序里的数据打交道,可以读取程序的数据,也可以删除程序的数据,当然,中间也会涉及一些权限的问题。 而以下方法是需要在子类实现的: · boolean onCreate() Called when the provider is being started. · Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,String sortOrder) 通过Uri进行查询,返回一个Cursor。 · Uri insert(Uri url, ContentValues values) 将一组数据插入到Uri 指定的地方,返回新inserted的URI。 · int update(Uri uri, ContentValues values, String where, String[] selectionArgs) 更新Uri指定位置的数据,返回所影响的行数。 · int delete(Uri url, String where, String[] selectionArgs) 删除指定Uri并且符合一定条件的数据,返回所影响的行数。 · String getType (Uri uri) 获取所查询URI的MIME类型,如果没有类型则返回null。 当我们不需要把数据提供给第三方应用程序使用的话,可以不实现Content Provider。 5. ContentResolver 外界的程序通过ContentResolver接口可以访问ContentProvider提供的数据,在Activity当中通过getContentResolver()可以得到当前应用的 ContentResolver实例。ContentResolver提供的接口和ContentProvider中需要实现的接口对应,具体可以查看API Doc,不过可以发现ContentResolver里面的方法很多都是final或者static的。在实际应用中,我们很少实现ContentResolver抽象类,更多时候通过getContentResolver()从一个Activity或其它应用程序组件的实现里获取一个ContentResolver: ContentResolver cr = getContentResolver(); 然后你可以使用这个ContentResolver的方法来和你感兴趣的任何内容提供器交互。 当初始化一个查询时,Android系统识别查询目标的内容提供器并确保它正在运行。系统实例化所有的ContentProvider对象;你从来不需要自己做。事实上,你从来不会直接处理ContentProvider对象。通常,对于每个类型的ContentProvider只有一个简单的实例。但它能够和不同应用程序和进程中的多个ContentProvider对象通讯。进程间的交互通过ContentResolver和ContentProvider类处理。 6. URI的说明 每个Content Provider都需要公开一个URI来标识它的数据集。一个控制多个数据集(多个表)的Content Provider为每一个数据集暴露一个单独的URI。而URIs都以字符串"content://"开始。这个content:形式表明了这个数据正被一个Content Provider控制着。 图片 将其分为A,B,C,D 4个部分: A:标准前缀,用来说明一个Content Provider控制这些数据,无法改变的; B:URI的权限部分,它定义了是哪个Content Provider提供这些数据。对于第三方应用程序,为了保证URI标识的唯一性,它必须是一个完整的、小写的 类名。这个标识在<provider> 元素的 authorities属性中说明: <provider name=".TransportationProvider" authorities="com.example.transportationprovider" . . . > C:用来判断请求数据类型的路径。Content Provider使用这些路径来确定当前需要生什么类型的数据。这可以是0或多个段长。如果内容提供器只暴露了一种数据类型(比如,只有火车),这个分段可以没有。如果提供器暴露若干类型,包括子类型,那它可以是多个分段长-例如,提供"land/bus", "land/train", "sea/ship", 和"sea/submarine"这4个可能的值。 D:被请求的特定记录的ID。如果URI中包含,表示需要获取的记录的ID;如果没有ID,就表示返回全部,这个分段和尾部的斜线会被忽略; 现在应该明白ContentResolver是通过URI来查询ContentProvider中提供的数据。除了URI以外,还必须知道需要获取的数据段的名称,以及此数据段的数据类型。如果你需要获取一个特定的记录,你就必须知道当前记录的ID,也就是URI中D部分。 现在我们来创建一个ContentProvider。按照官方的说法,“要创建一个内容提供器,你必须: · 建立一个保存数据的系统。大多数Content Provider使用Android的文件储存方法或SQLite数据库来存放它们的数据,但是你可以用任何你想要的方式来存放数据。实现SQLiteOpenHelper类来帮助你创建一个数据库以及SQLiteDatabase类来管理它。 · 扩展ContentProvider类来提供数据访问接口。 · 在清单manifest文件中为你的应用程序声明这个Content Provider(AndroidManifest.xml)。” 1.设计好一个实体类,定义好需要公开的变量,column,URI等 2.创建内部类实现SQLiteOpenHelper,用于创建更新数据表,以及后面的获取SQLiteDatabase引用 3.编写ContentProvider子类或者其他封装数据库操作的自定义类,包含上面的内部类 4.在AndroidManifest.xml的application element里面添加子element provider (和element activity同一层),声明这个Content Provider 本文转自 Icansoft 51CTO博客,原文链接: http://blog.51cto.com/android/393455
不知道大家用笔记本的时候有没有遇到过这种情况,当你想在键盘敲K,输出的却是2,敲M,输出的却是0。其实这是你不小心,启动了键盘上的小键盘(笔记本因为键盘容量的问题,不像台式电脑的键盘一样,有设在右边专用的数字小键盘)。 解决的方法:同时按下Fn键+NumLock键(Fn键+Insert键),这样就能解除小键盘的使用了 本文转自 lingdududu 51CTO博客,原文链接: http://blog.51cto.com/liangruijun/627955
当我们需要截取的页面,窗口带有滚动条的时候,QQ截图工具,PrintScreen快捷键都只能截图电脑屏幕的页面,滚动条下拉的页面就无法截取到,下面介绍两种截取滚动页面,窗口的方法。 第一种:使用HyperSnap-DX截图工具 下载地址:http://www.skycn.com/soft/2270.html 1.启动HyperSnap-DX--捕捉--正页.滚动(或者直接用快捷键CTRL+SHIFT+S) 2.在你想要截取的滚动页面,窗口上将鼠标指针移动到滚动条最下端点一下向下的箭头,屏幕会向下移 动并自动捕捉画面。 第二种:使用Snagit截图工具 1.启动Snagit--滚动窗口 (Web 页) 下载地址:http://www.duote.com/soft/978.html 2.在你想要截取的滚动页面,窗口上点击鼠标左键,屏幕会向下移 动并自动捕捉画面。 本文转自 lingdududu 51CTO博客,原文链接: http://blog.51cto.com/liangruijun/628438
Android系统中提供了一种文件读写的方法,可以将一些数据以文件的形式保存在设备中。比如一些word文档,PDF文档,图片,音频,视频文件等。 使用文件读写方法的步骤: 1.调用Context.openFileInput()方法获得Java文件输入流(FileInputStream) 2.调用Context.openFileOutput()方法获得java文件输出流(FileOutputStream) 3.使用Resources.openRawResource(R.raw.DataFile)方法返回InputStream 下面的具体实例,在一个Activity里面创建两个EditText和两个Button,第一个EditText和Button将EditText的内容写到文件file.txt文件中。第二个EditText和Button将内容从文件file.txt中读取出来显示。文件被默认保存在/data/data/package/files下面。 MainActivity.java package com.android.file; import java.io.FileInputStream; import java.io.FileOutputStream; import android.app.Activity; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.EditText; public class MainActivity extends Activity { //声明文件名字符串常量 private static final String FILE_NAME="file.txt"; private Button writeBtn,readBtn; private EditText writeText,readText; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); writeBtn = (Button)findViewById(R.id.Button1); readBtn = (Button)findViewById(R.id.Button2); writeText = (EditText)findViewById(R.id.EditText1); readText = (EditText)findViewById(R.id.EditText2); writeBtn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { //写内容 write(writeText.getText().toString()); } }); readBtn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { //读内容 readText.setText(read()); } }); } private String read(){ try { //实例化文件输入流对象 FileInputStream fis = openFileInput(FILE_NAME); //定义缓存数组 byte[] buffer = new byte[fis.available()]; //读到缓冲区 fis.read(buffer); return new String(buffer); } catch (Exception e) { e.printStackTrace(); } return null; } private void write(String content){ try { //实例化文件输出流 //openFileOutput(String name, int mode) //第一个参数文件名 //第二个是模式 //MODE_APPEND表示要创建的文件存在则新写入的数据不会覆盖以前的数据。 FileOutputStream fos = openFileOutput(FILE_NAME, MODE_APPEND); //写内容 fos.write(content.getBytes()); //关闭文件流 fos.close(); } catch (Exception e) { e.printStackTrace(); } } } main.java <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="请被文本输入内容" /> <EditText android:text="" android:id="@+id/EditText1" android:layout_width="fill_parent" android:layout_height="wrap_content" android:height="100px" /> <Button android:id="@+id/Button1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="写数据" /> <EditText android:text="" android:id="@+id/EditText2" android:layout_width="fill_parent" android:layout_height="wrap_content" android:height="100px" /> <Button android:id="@+id/Button2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="读数据" /> </LinearLayout> 效果图: 在终端下输入“adb shell”命令进入Android系统查看一下我们的文件是否写入成功。 本文转自 lingdududu 51CTO博客,原文链接:http://blog.51cto.com/liangruijun/660540
下面是一个简单的计算标准体重的实例,选择自己的性别,再输入自己的身高,点击Button就能在Toast显示自己的标准体重,看看自己的体重有没有符合标准哦。 计算标准体重的方法: 男性:(身高cm-80)×70﹪=标准体重 女性:(身高cm-70)×60﹪=标准体重 BMIActivity.java package com.lingdududu.bmi; import java.text.DecimalFormat; import java.text.NumberFormat; import android.app.Activity; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.EditText; import android.widget.RadioButton; import android.widget.Toast; /* * @author lingdududu * 该程序的功能是用户选择自己的性别和输入自己的身高,然后点击按钮,就能在Toast显示出自己的标准体重 */ public class BMIActivity extends Activity { /** Called when the activity is first created. */ private Button countButton; private EditText heighText; private RadioButton maleBtn, femaleBtn; String sex = ""; double height; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); //调用创建视图的函数 creadView(); //调用性别选择的函数 sexChoose(); //调用Button注册监听器的函数 setListener(); } //响应Button事件的函数 private void setListener() { countButton.setOnClickListener(countListner); } private OnClickListener countListner = new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub Toast.makeText(BMIActivity.this, "你是一位"+sexChoose()+"\n" +"你的身高为"+Double.parseDouble(heighText.getText().toString())+"cm" +"\n你的标准体重为"+getWeight(sexChoose(), height)+"kg", Toast.LENGTH_LONG) .show(); } }; //性别选择的函数 private String sexChoose(){ if (maleBtn.isChecked()) { sex = "男性"; } else if(femaleBtn.isChecked()){ sex = "女性"; } return sex; } //创建视图的函数 public void creadView(){ //txt=(TextView)findViewById(R.id.txt); countButton=(Button)findViewById(R.id.btn); heighText=(EditText)findViewById(R.id.etx); maleBtn=(RadioButton)findViewById(R.id.male); femaleBtn=(RadioButton)findViewById(R.id.female); //txt.setBackgroundResource(R.drawable.bg); } //标准体重格式化输出的函数 private String format(double num) { NumberFormat formatter = new DecimalFormat("0.00"); String str = formatter.format(num); return str; } //得到标准体重的函数 private String getWeight(String sex, double height) { height = Double.parseDouble(heighText.getText().toString()); String weight = ""; if (sex.equals("男性")) { weight =format((height - 80) * 0.7); } else { weight = format((height - 70) * 0.6); } return weight; } } main.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="@drawable/pic" > <TextView android:id="@+id/txt" android:layout_width="fill_parent" android:layout_height="wrap_content" android:gravity="center" android:text="@string/hello" android:textSize="16px" /> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/sex" /> <RadioGroup android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="horizontal" > <RadioButton android:id="@+id/male" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="男" /> <RadioButton android:id="@+id/female" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="女" /> </RadioGroup> <TextView android:layout_width="fill_parent" android:layout_height="26px" android:text="@string/heigh" /> <EditText android:id="@+id/etx" android:layout_width="fill_parent" android:layout_height="wrap_content" /> <Button android:id="@+id/btn" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/count" /> </LinearLayout> 效果图: 本文转自 lingdududu 51CTO博客,原文链接: http://blog.51cto.com/liangruijun/700077
一 服务器 以dell 官网为准 戴尔PowerEdge R410 //入门级服务器 基本参数 产品类别:机架式 产品结构:1U 处理器 CPU类型:Intel 至强5xxx CPU型号:Xeon E5606 CPU频率:2.13GHz 最大CPU数量:2颗 制程工艺:32nm 三级缓存:8MB 总线规格:QPI 4.8GT/s CPU核心:四核 CPU线程数:四线程 主板 主板芯片组:Intel 5500 扩展槽:1×PCI插槽 内存 内存类型:DDR3 内存容量:2-4-8-16GB 内存插槽数量:8 最大内存容量:128GB 存储 硬盘接口类型:SAS 最大硬盘容量:8TB 硬盘描述:4块2TB SAS/SATA 3.5英寸硬盘 RAID卡描述:SAS 6i 光驱:DVD 网络 网络控制器:双端口千兆网卡 显示系统 显示芯片:Matrox G200eW,8MB显存 管理及其他 系统管理:配戴尔管理控制台的Dell OpenManage BMC,符合IPMI2.0标准 可选:iDRAC6 Express,iDRAC6 Enterprise和Vflash 电源性能 (非冗余) 电源数量:1个 电源电压:100-240V 电源功率: 480W 外观特征 产品尺寸:43×434×627.1mm 戴尔PowerEdge R510 //2u服务器,海量存储 基本参数 产品类别:机架式 产品结构:2U 处理器 CPU类型:Intel 至强5xxx 系列 CPU型号:Xeon E5620 CPU频率:2.4GHz 智能加速主频:2.666GHz 最大CPU数量:2颗 制程工艺:32nm 三级缓存:12MB 总线规格:QPI 5.86GT/s CPU核心:四核 CPU线程数:八线程 主板 主板芯片组:Intel 5500 扩展槽:1×PCI-E G2 x8插槽 2×PCI-E G2 x4插槽(均配有x8接头) 1×PCI-E G2 x4存储插槽(配有x8接头) 内存 内存类型:DDR3 内存容量:2-4-8-16GB 内存插槽数量:8 最大内存容量:128GB 存储 硬盘接口类型:SAS 最大硬盘容量:24.6TB 硬盘描述:12块2TB SAS/SATA 3.5英寸 硬盘 RAID卡描述:PERC H700 光驱:DVD 网络 网络控制器:Broadcom 5716 Gigabit NIC双端口网卡 显示系统 显示芯片:Matrox G200eW,8MB显存 管理及其他 系统管理:采用戴尔管理控制台的Dell OpenManage BMC,符合IPMI 2.0标准 可选:iDRAC6 Express,iDRAC6 Enterprise和Vflash 电源性能 (冗余) 电源数量:1/2个 电源电压:100-240V 电源功率: 750w 外观特征 产品尺寸:86.4×436.6×609.6mm 戴尔PowerEdge R610 //适用于虚拟化 VMware 基本参数 产品类别:机架式 产品结构:1U 处理器 CPU类型:Intel 至强5xxx CPU型号:Xeon E5xxx CPU频率:2.13GHz 最大CPU数量:2颗 制程工艺:32nm 二级缓存:1MB 三级缓存:4MB 总线规格:QPI 4.8GT/s CPU核心:四核(Gainestown) CPU线程数:四线程 主板 主板芯片组:Intel 5520 扩展槽:2× x8(二代插槽) 内存 内存类型:DDR3 内存容量:2-4-8-16GB 内存插槽数量:12 最大内存容量:192GB 存储 硬盘接口类型:SAS 最大硬盘容量:12TB 硬盘描述:6块2TB SAS/SATA 2.5英寸 硬盘 RAID卡描述:PERC 6i 网络 网络控制器:两个Broadcom NetXtreme II 5709c双端口千兆网卡 显示系统 显示芯片:集成 Matrox G200,8MB显存 管理及其他 散热系统:标准冗余冷却风扇 系统管理:Dell OpenManage 电源性能 (冗余) 电源数量:1/2个 电源电压:100-240V 电源功率: 502w 外观特征 产品尺寸:42.6×482.4×772mm 戴尔PowerEdge R710 //扩展性超强,经常用于数据库文件服务器等。 基本参数 产品类别:机架式 产品结构:2U 处理器 CPU类型:Intel 至强5xxx CPU型号:Xeon E5xxx CPU频率:2.4GHz 智能加速主频:2.666GHz 最大CPU数量:2颗 制程工艺:32nm 三级缓存:12MB 总线规格:QPI 5.86GT/s CPU核心:四核 CPU线程数:八线程 主板 主板芯片组:Intel 5520 扩展槽:2×PCI-E x8 2×PCI-E x4 或1×PCI-E x16 2×PCI-E x4 内存 内存类型:DDR3 内存容量:2-4-8-16GB 内存插槽数量:18 最大内存容量:192GB 存储 硬盘接口类型:SAS 最大硬盘容量:12TB/16TB 硬盘描述:6块2TB SAS热插拔硬盘 内部硬盘架数:最大支持6块3.5英寸SAS/SATA硬盘 | 最大支持8块2.5英寸SAS/SATA硬盘 RAID模式:PERC6i 光驱:DVD-ROM 网络 网络控制器:四千兆网卡 显示系统 显示芯片:Matrox G200 管理及其他 散热系统:可选冗余冷却 系统管理:远程管理卡 电源性能 (冗余) 电源数量:1/2个 电源电压:100-240V 电源功率: 570w / 870w 外观特征 产品尺寸:86.4×443.1×680.7mm 戴尔PowerEdge R910 //适用于大容量内存,高密度计算服务。 基本参数 产品类别:机架式 产品结构:4U 处理器 CPU类型:Intel 至强7xxx CPU型号:Xeon E7520 CPU频率:1.866GHz 智能加速主频:1.866GHz 标配CPU数量:2颗 最大CPU数量:4颗 制程工艺:45nm 三级缓存:18MB 总线规格:QPI 4.8GT/s CPU核心:四核 CPU线程数:八线程 主板 主板芯片组:Intel 7500 内存 内存类型:DDR3 内存容量:4-8-16-32GB 内存插槽数量:64 最大内存容量:2TB 存储 硬盘接口类型:SAS 最大硬盘容量:16TB 硬盘描述:16块1TB 内部硬盘架数: 最大支持16块2.5英寸SAS/SATA硬盘 RAID模式:PERC H800 光驱:DVD-ROM 显示系统 显示芯片:Matrox G200eW,8MB显存 管理及其他 系统管理:具有戴尔管理控制台的Dell OpenManage BMC,符合IPMI2.0,iDRAC6 Express 统一服务器配置器 生命周期控制器可通过以下可选项启用:iDRAC6 Express、iDRAC6 Enterprise和Vflash 电源性能 电源类型:4个750瓦(智能节能PSU)或4个1100瓦(高输出PSU) 外观特征 产品尺寸:172.6×482×753mm 二 交换机 CISCO WS-C3750E-24PD-S 详细参数 主要参数 产品类型:企业级交换机 应用层级:二层 传输速率:10/100/1000Mbps 产品内存:DRAM内存:256MB FLASH内存:64MB 交换方式:存储-转发 背板带宽:68Gbps 包转发率:65.5Mpps MAC地址表:12K 端口参数 端口结构:非模块化 端口数量:26个 端口描述:24个以太网10/100/1000Mbps端口,2个基于X2的万兆以太网端口 传输模式:支持全双工 功能特性 网络标准:IEEE 802.1s,IEEE 802.1w,IEEE 802.1x,IEEE 802.3ad,IEEE 802.3af,IEEE 802.3x,IEEE 802.1D,IEEE 802.1p,IEEE 802.1Q,IEEE 802.3,IEEE 802.3u,IEEE 802.3ab,IEEE 802.3z 堆叠功能:可堆叠 VLAN:支持 QOS:支持 其它参数 状态指示灯:连接完整性,禁用,活动,速度和全双工指示器,系统,RPS和带宽利用率指示器 电源功率:370W PoE,能为每个端口提供15.4W 产品尺寸:44.5×445×460mm CISCO WS-C3750G-24TS-S详细参数 主要参数 产品类型:企业级交换机 应用层级:三层 传输速率:10/100/1000Mbps 产品内存:128MB 交换方式:存储-转发 背板带宽:32Gbps 包转发率:38.7Mpps MAC地址表:12K 端口参数 端口结构:非模块化 端口数量:28个 端口描述:24个以太网10/100/1000端口,4个基于SFP上行链路端口 接口介质:10/100/1000Base-TX 1000Base-FX/SX 传输模式:支持全双工 功能特性 网络标准:IEEE 802.3,IEEE 802.3u,IEEE 802.3z,IEEE 802.3ab 堆叠功能:可堆叠 VLAN:支持 QOS:支持 网络管理:SNMP,CLI,Web,管理软件 其它参数 产品尺寸:295×445×66mm 产品重量:5.68kg CISCO WS-C3560G-24TS-S详细参数 主要参数 产品类型:企业级交换机 应用层级:三层 传输速率:10/100/1000Mbps 产品内存:DRAM内存:128MB 交换方式:存储-转发 背板带宽:32Gbps 包转发率:38.7Mpps MAC地址表:12K 端口参数 端口结构:非模块化 端口数量:28个 端口描述:24个以太网10/100/1000Mbps端口,4个SFP上行链路端口 扩展模块:2 传输模式:支持全双工 功能特性 网络标准:IEEE 802.3,IEEE 802.3u,IEEE 802.3z,IEEE 802.3ab 堆叠功能:可堆叠 VLAN:支持 QOS:支持 网络管理:网管功能SNMP,CLI,Web,管理软件 其它参数 电源电压:AC 100-240V,50-60Hz 产品尺寸:378×445×44mm 产品重量:5.4kg CISCO WS-C2960G-24TC-L详细参数 主要参数 产品类型:智能交换机 应用层级:二层 传输速率:10/100/1000Mbps 产品内存:64MB 交换方式:存储-转发 背板带宽:24Gbps 包转发率:35.7Mpps MAC地址表:8K 端口参数 端口结构:非模块化 端口数量:24个 端口描述:24个以太网10/100/1000Mbps端口,其中有4个为两用端口 扩展模块:4 传输模式:全双工/半双工自适应 功能特性 网络标准:.. VLAN:支持 QOS:支持 网络管理:Web浏览器,SNMP,CLI 其它参数 状态指示灯:每端口,系统 电源电压:AC 100-240V,50-60Hz,1.3-0.8A 产品尺寸:44×445×328mm 产品重量:4.5kg 扩展 服务器 vFlash SD 卡和管理 vFlash 分区 PowerEdge 系列服务器 系统硬件用户手册 以 R610 服务器为例,其它型号修改红色字即可。 http://supportapj.dell.com/support/edocs/systems/peR610/cs/HOM/HTML/about.htm 交换机 SFP 模块 IEEE 802 10吉比特以太网路 Catalyst 3750-E系列交换机 思科常见产品资料 #update 20121112 PowerEdge_R620 PowerEdge_R720 #update 20121120 1. 戴尔第12代PowerEdge服务器 概述 戴尔的第12代服务器是在全球7700多个客户反馈的基础上设计出来的。12G服务器在设计上充分考虑到了客户对于以下几个方面的需求: 性能与容量 可靠性与安全性 高效的使用与管理 戴尔的第12代服务器在以上几方面推出了一系列新功能和改进,其中包括: 使用新一代Intel Xeon E5-2600 CPU、支持最多24条768GB内存,提高计算性能 增强的I/O性能,支持第3代PCIe技术 使用新一代PERC卡、SSD CacheCade与PCIe SSD技术,提高存储性能与可靠性 支持内置/外置GPU,提高浮点运算性能 ?? 使用双冗余SD卡提高虚拟化的可靠性 全面支持10GbE网络 可更换的网络子卡以及网卡分区(NPAR) – 更灵活的网络选择 将远程控制卡iDRAC与生命周期控制器结合,实现无代理的服务器管理以及配件更换后自动的固件升级 更高效的电源选择与便捷的电源管理 遵从戴尔新风数据中心解决方案标准 OpenManage Essential – 新一代功能强大方便易用的系统管理软件 产品型号与规格 戴尔这次春季发布的首批12G服务器主要覆盖主流服务器市场,包括: 塔式服务器:PowerEdge T620 机架式服务器:PowerEdge R620, R720, R720xd 刀片式服务器:PowerEdge M620 微服务器:PowerEdge C6220 ?? 2. Intel Xeon E5-2603详细参数基本参数 CPU类型:至强 CPU系列:Xeon E5-2600系列 CPU内核 CPU架构:64位 核心数量:四核心 工作功率:80W 制作工艺:32纳米 线程数量:4 CPU频率 主频:1800MHz CPU缓存 L3缓存:10MB 参考2 3. PowerEdge RAID Controller (PERC H710 mini) 参考2 :RAID阵列的迁移 4. 新一代的远程访问管理卡iDRAC 7 (坑爹的) 服务器自带硬件,不过需要license才可以升级至iDRAC Enterprise版本。 # 本文转自 dongnan 51CTO博客,原文链接:http://blog.51cto.com/dngood/786655
监控离不开数据采集,经常使用的Mrtg ,Cacti,Zabbix,等等监控软件都是通过snmp 协议进行数据采集的! 1 什么是snmp 协议? 简单网络管理协议(SNMP,Simple Network Management Protocol)构成了互联网工程工作小组(IETF,Internet Engineering Task Force)定义的internet协议簇的一部分。该协议能够支持网络管理系统,用以监测连接到网络上的设备是否有任何引起管理上关注的情况。它由一组网络管理的标准组成,包含一个应用层协议(application layer protocol)、数据库模型(database schema),和一组资料物件。 2 linux 系统下 snmp 服务配置 2.1 snmpd 服务安装 yum install net-snmp* 2.2 编辑snmpd.conf 配置文档 vim /etc/snmp/snmpd.conf 41行 1将default 改为监控服务器ip;2 将public 改成复杂些的识别的字符串 com2sec notConfigUser 10.0.100.70 dongnan 62行 1将systemview 改为all,供所有snmp 访问权限 access notConfigGroup "" any noauth exact all none none 85行 将#注释符号去掉 view all included .1 80 2.3 启动 snmpd 服务 /etc/init.d/snmpd start 2.4 验证snmpd 服务 //snmpd 使用 tcp/udp 161 端口 grep 'Simple Net Mgmt Proto' /etc/services snmp 161/tcp # Simple Net Mgmt Proto snmp 161/udp # Simple Net Mgmt Proto lsof -i :161 COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME snmpd 3734 root 11u IPv4 13174 UDP *:snmp ps -ef | grep 'snmpd' root 3734 1 0 09:34 ? 00:00:00 /usr/sbin/snmpd -Lsd -Lf /dev/null -p /var/run/snmpd.pid -a 2.5 修改snmpd 日志级别 //以上操作能够满足snmpd 服务正常使用,不过snmpd 默认日志级别将会在/var/log/message 写入大量snmp 信息,这样会影响我们察看系统日志,所以我们需要更改下! Mar 1 09:55:01 monitor snmpd[3734]: Connection from UDP: [127.0.0.1]:37535 Mar 1 09:55:01 monitor snmpd[3734]: Received SNMP packet(s) from UDP: [127.0.0.1]:37535 Mar 1 09:55:01 monitor snmpd[3734]: Connection from UDP: [127.0.0.1]:47836 Mar 1 09:55:01 monitor snmpd[3734]: Received SNMP packet(s) from UDP: [127.0.0.1]:47836 //注释原有的OPTINOS,添加下面的一行,重启snmpd 服务即可。 vim /etc/init.d/snmpd #OPTIONS="-Lsd -Lf /dev/null -p /var/run/snmpd.pid -a" OPTIONS="-LS 4 d -p /var/run/snmpd.pid -a" /etc/init.d/snmpd restart Stopping snmpd: [ OK ] Starting snmpd: [ OK ] 2.6 使用snmpwalk 命令验证 snmpwalk -v 1 -c dongnan 192.168.57.82 snmpwalk -v 2c -c dongnan 192.168.57.71 -v是指版本,-c 是指密钥,获取到系统信息则正常! 注意:以上操作在 RHEL5/Centos5 系统使用rpm 包方式安装的SNMP 结束 更多欢迎到此讨论 37275208 (已满) 71921660 本文转自 dongnan 51CTO博客,原文链接:http://blog.51cto.com/dngood/793299
公司没有网工所以在做项目时又担负起网工的角色,在做项目的过程中常常会用到以下术语,下面是我做项目总结的,拿来分享下如不正确请指正! 术语一 1000Base-* 吉比特以太网(英语:GbE, Gigabit Ethernet,或1 GigE)是一个描述各种以吉比特每秒速率进行以太网帧传输技术的术语, 由IEEE 802.3-2005标准定义。该标准允许通过集线器连接的半双工千兆连接,但是在市场上利用交换机的全双工连接才是标准。 标准 吉比特以太网共有4种不同的物理层标准,包括光纤(1000BASE-X)、双绞线(1000BASE-T)或平衡的铜缆(1000BASE-CX)。 1000BASE-X 1000BASE-X在产业中用来指通过光纤传输的吉比特以太网,包括1000BASE-SX,-LX,-BX10, 或非标准的-LH/-ZX。(LX--长距/单模;LH--超长/单模) 1000BASE-SX 1000BASE-SX是采用 Multi Mode Optical Fiber, 以 Gigabit Ethernet 为标准, 使用850毫微米红外光(NIR)波长. 62.5/125 μm材质光纤标准指定距离在220m之间, 虽然实践上,50/125 μm材质光纤则可延伸至500m以上。 通常普遍使用于大楼内部链接口的 典型的光学力量参量: 最大值为 -5 dBm; 接收器敏感性则在 -14 dBm 1000BASE-LX 1000BASE-LX对应于802.3z标准,既可以使用单模光纤也可以使用多模光纤。 1000BASE-LX所使用的光纤主要有:62.5μm多模光纤、50μm多模光纤和9μm单模光纤。 其中使用多模光纤的最大传输距离为550m,使用单模光纤的最大传输距离为3千米。1000BASE-LX采用8B/10B编码方式。 1000BASE-T 1000BASE-T(也被称为IEEE 802.3ae)是一个用于铜线的千兆以太网标准。 每一个1000BASE-T 网段最大可以达到100米(328英尺),并且要求传输线最差为CAT-5。 CAT-5e和CAT-6也可以用,并且是经常建议使用的。 1000BASE-T需要四对差分线, 并且对比100BASE-TX标准来说,对传输线的要求比后者要高的多。 如果两个千兆比特速度的器件通过四对不符合CAT-5要求的线连接,许多的帧校验错误和重传现象将会发生。 术语二 千兆以太网路接口转换器 GBIC 千兆以太网路接口转换器(英文:Gigabit Interface Converter,简称GBIC”,是一种通常用在千兆以太网及光纤通道的信号转换器。 透过此转换器的标准规范,千兆以太网络设备的端口可以直接对应各种实体传输接口,包括铜线、多模光纤与单模光纤。 对网络设备制造商而言,只要将设备设计成支援GBIC端口就能够支援各种传输接口,而不需针对各种接口另行设计端口,可以省下成本。 对使用者而言,则在购买设备时不需注重端口规格,只需选择所需要的传输接口所对应的GBIC即可,而且也很容易随着需要做调整。 现在的GBIC已经有小型化的版本(Small Form-factor Pluggable, SFP),又称迷你GBIC(mini GBIC), 尺寸大概只有原来的一半,不但节省成本,网络设备的端口密度也可以增加一倍 术语三 小封装可插拔收发器(SFP) 小封装热插拔收发器(SFP, Small form-factor pluggable transceiver),是一种小型的可热插拔的光学收发器, 用于电信和数据通信中光通信应用。SFP联接网络设备如交换机、路由器等设备的主板和光纤或UTP线缆。SFP是一些光纤器件提供商支持的工业规格. SFP收发器支持SONET、Gigabit Ethernet、光纤通道(Fiber Channel)以及一些其他通信标准。此标准扩展到了SFP+, 能支持10.0 Gbit/s传输速率,包括8 gigabit光纤通道和10GbE。引入了光纤和铜芯版本的SFP+模块版本, 与模块的Xenpak、X2或XFP版本相比,SFP+模块将部分电路留在主板实现,而非模块内实现。 SFP类型 SFP收发器有多种不同的发送和接收类型,用户可以为每个链接选择合适的收发器,以提供基于可用的光纤类型(如多模光纤或单模光纤)能达到的"光学性能"。 可用的光学SFP模块一般分为如下类别:850纳米波长/550米距离的 MMF (SX)、1310纳米波长/10公里距离的 SMF (LX)、1550 纳米波长/40公里距离的XD、 80公里距离的ZX、120公里距离的EX或EZX,以及DWDM。SFP收发器也提供铜缆接口,使得主要为光纤通信设计的主机设备也能够通过UTP网络线缆通信。 也存在波分复用(CWDM)以及单光纤"双向"(1310/1490纳米波长上行/下行)的SFP。 商用SFP收发器能够提供速率达到4.25 G bps。10 Gbps 收发器的几种封装形式为XFP,以及与SFP封装基本一致的新的变种"SFP+"。 SFP 标准化 SFP收发器由一个竞争厂商之间的多边协议(MSA)进行规范。SFP根据GBIC接口进行设计, 允许比GBIC更大的端口密度(主板边上每英寸的收发器数目),因此SFP也被称作“mini-GBIC”。 与此相关的小封装收发器(SFF transceiver)在尺寸上比SFP要小,但SFF是作为一种针脚 (as a pin through-hole device)垂直插入到主机板上(不可热插拔),而不是像SFP(支持热插拔)一样的平行插入到边卡插槽上。 术语四 光纤接头(光纤跳线) 光纤接头是光纤的末端装置,用意是让光纤的接续更快速方便,而不需要熔接。接头的接续让两条不同的光纤的光可以通过。 接头有很多种,不同接头的差别在接头大小及接续方法的不同。使用上通常在同一系统会采用同一种接头。 类型 (部分) 名称(完整名称) 中文名称 接续方式 应用方式 LC(Lucent Connector / Local Connector) Lucent 接头 / Local 接头 滑扣 高密度连接 SC(Subscriber Connector / Standard Connector) 用户端接头 / 标准接头 滑扣 数据通讯 术语五 光纤跳线的交叉连接 1 光纤跳线的交叉连接 所有交换机的光纤端口都是2个,分别是一发一收。当然,光纤跳线也必须是2根,否则端口之间将无法进行通讯。 当交换机通过光纤端口级联时,必须将光纤跳线两端的收发对调,当一端接“收”时,另一端接“发”。 同理,当一端接“发”时,另一端接“收”如果光纤跳线的两端均连接“收”或“发”,则该端口的LED指示灯不亮,表示该连接为失败。 只有当光纤端口连接成功后,LED指示灯才转为绿色。 2 光纤跳线及光纤端口类型 光纤跳线分为单模光纤和多模光纤。交换机光纤端口、跳线都必须与综合布线时使用的光纤类型相一致, 也就是说,如果综合布线时使用的多模光纤,那么,交换机的光纤接口就必须执行1000Base-SX标准, 也必须使用多模光纤跳线;如果综合布线时使用的单模光纤,那么,交换机的光纤接口就必须执行1000Base-LX/LH标准,也必须使用单模光纤跳线。 需要注意的是,多模光纤有两种类型,即62.5/125μm和50/125μm。虽然交换机的光纤端口完全相同,而且两者也都执行1000Base-SX标准, 但光纤跳线的芯径必须与光缆的芯径完全相同,否则,将导致连通性故障。 另外,相互连接的光纤端口的类型必须完全相同, 或者均为多模光纤端口,或者均为单模光纤端口。一端是多模光纤端口,而另一端是单模光纤端口,将无法连接在一起。 3 传输速率与双工模式 与1000Base-T不同,1000Base-SX、1000Base-LX/LH和1000Base-ZX均不能支持自适应,不同速率和双工工作模式的端口将无法连接并通讯。 因此,要求相互连接的光纤端口必须拥有完全相同的传输速率和双工工作模式,既不可将1000Mbps的光纤端口与100Mbps的光纤端口连接在一起, 也不可将全双工模式的光纤端口与半双工模式的光纤端口连接在一起,否则,将导致连通性故障。 以下 cisco 2960G 交换机 传输速率,其中 1000BaseTX为RJ45双绞线,1000BaseSX SFP为多模光纤 Port Name Status Vlan Duplex Speed Type Gi0/1 connected 1 a-full a-1000 10/100/1000BaseTX Gi0/2 notconnect 1 auto auto 10/100/1000BaseTX Gi0/3 connected 1 a-full a-1000 10/100/1000BaseTX Gi0/45 connected 1 a-full a-1000 1000BaseSX SFP 扩展 更详细的 光模块种类很多,如何区分呢? 光纤模块的构成有:发射机(TOSA),接收(ROSSA)线路板IC 外部配件 光纤模块接口分为:FC型、SC型、LC型、ST型、FTRJ型、RJ45 光收发一体模块分类 按照速率分:以太网应用的100Base(百兆)、1000Base(千兆)、10GE SDH应用的155M、622M、2.5G、10G 按照封装分:1×9、SFF、SFP、GBIC、SFP+、XFP、X2、XENPAK 1×9封装 —— 焊接型光模块,一般速率有52M/155M/622M/1.25G,多采用SC接口 SFF封装 —— 焊接小封装光模块,一般速率有155M/622M/1.25G/2.25G/4.25G,多采用LC接口 GBIC封装 —— 热插拔千兆接口光模块,采用SC接口 SFP封装 —— 热插拔小封装模块,目前最高数率可达155M/622M/1.25G/2.125G/4.25G/8G/10G,多采用LC接口 XENPAK封装 —— 应用在万兆以太网,采用SC接口 XFP封装 —— 10G光模块,可用在万兆以太网,SONET等多种系统,多采用LC接口 按照激光类型分:LED、VCSEL、FP LD、DFB LD 按照发射波长分:850nm、1310nm、1550nm等等 按照使用方式分:非热插拔(1×9、SFF),可热插拔(GBIC、SFP、XENPAK、XFP) 光纤模块又分单模和多模 单模光纤使用的光波长为1310nm或1550 nm。 单模光纤的尺寸为9-10/125μm 它的传输距离一般 10KM 20kM 40KM 70KM 120KM 多模光纤使用的光波长多为850 nm或1310nm. 多模光纤50/125μm或62.5/125μm两种,它的传输距离也不一样,一般千兆环境下50/125μm线可传输550M,62.5/125μm只可以传送330M。 从颜色上可以区分单模光纤和多模光纤。单模光纤外体为黄色,多模光纤外体为橘红色。 光纤模块的电频:PECL 电流:18豪安,电压:3.3V ,5V 温度:0~70 ,-40~70(工业级) 光模块常用的一些符号: SX MM(850nm 550M) LX SM(1310nm 15KM) LHSM(1310nm 40km) ZX(1550nm 70KM) EZX(1550nm120KM) SR LR ER ZR 结束 更多欢迎到此讨论 71921660 37275208 (已满) 本文转自 dongnan 51CTO博客,原文链接:http://blog.51cto.com/dngood/803748
D5-Nginx_conf 与 Php-fpm_conf 1 nginx.conf 1.1 nginx 主配置文件 $ cat nginx.conf user www www; worker_processes 2; error_log /usr/local/nginx/logs/nginx_error.log crit; pid /usr/local/nginx/logs/nginx.pid; worker_rlimit_nofile 65535; events { use epoll; worker_connections 65535; } http { include mime.types; default_type application/octet-stream; charset utf8; server_tokens off; server_name_in_redirect off; server_names_hash_bucket_size 128; client_header_buffer_size 32k; large_client_header_buffers 4 32k; client_max_body_size 8m; sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 60; fastcgi_connect_timeout 300; fastcgi_send_timeout 300; fastcgi_read_timeout 300; fastcgi_buffer_size 64k; fastcgi_buffers 4 64k; fastcgi_busy_buffers_size 128k; fastcgi_temp_file_write_size 128k; gzip on; gzip_min_length 1k; gzip_buffers 4 16k; gzip_http_version 1.0; gzip_comp_level 2; gzip_types text/plain application/x-javascript text/css application/xml; gzip_vary on; #limit_zone crawler 10m; log_format access '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" $http_x_forwarded_for'; server { listen 0.0.0.0:80; server_name check.test.com; index index.html index.htm index.php; #autoindex on; #autoindex_localtime on; root /usr/local/nginx/html/; access_log /usr/local/nginx/logs/access.log access; } include vhosts/*; } 1.2 虚拟主机配置文件 $ cat vhosts/www.test.com server { listen 0.0.0.0:80; server_name www.test.com; index index.html index.htm index.php; root /var/www/html/www; location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$ { expires 300d; } error_page 404 = /404.html; location ~ \.(js|css|htm|html|shtml)$ { expires 60m; } access_log /var/log/httpd/www/access.log access; } $ cat vhosts/bbs.test.com server { listen 0.0.0.0:80; server_name bbs.test.com forum.test.com; index index.shtml index.php index.html; root /var/www/html/bbs; location ~ .*\.(php|php5)?$ { fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME /var/www/html/bbs$fastcgi_script_name; include fastcgi_params; } location ^~ /iso/ { proxy_pass http://192.168.57.71/iso/; } location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$ { expires 300d; } location ~ .*\.(js|css)?$ { expires 60m; } access_log /var/log/httpd/bbs/access.log access; } $ cat vhosts/blog.test.com server { listen 0.0.0.0:80; server_name blog.test.com t.test.com; index index.shtml index.php index.html; root /var/www/html/blog; location ~ .*\.(php|php5)?$ { fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME /var/www/html/blog$fastcgi_script_name; include fastcgi_params; } location ^~ /iso/ { proxy_pass http://192.168.57.71/iso/; } location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$ { expires 300d; } location ~ .*\.(js|css)?$ { expires 60m; } access_log /var/log/httpd/blog/access.log access; } 2 php-fpm.conf $ grep -Ev '^$|^;|^ ' /usr/local/php/etc/php-fpm.conf (1GB 内存) [global] pid = run/php-fpm.pid error_log = log/php-fpm.log log_level = notice [www] listen = 127.0.0.1:9000 user = www group = www pm = static pm.max_children = 35 pm.start_servers = 20 pm.min_spare_servers = 5 pm.max_spare_servers = 35 pm.max_requests = 500 以下摘自 http://os.51cto.com/art/201111/304577.htm php-fpm对于进程的管理存在两种风格static和dynamic,和之前的版本的进程管理其实还是一样的,只是将apache-like改成了dynamic这样更容易理解; 如果设置成static php-fpm进程数自始至终都是pm.max_children指定的数量,不再增加或减少; 如果设置成dynamic 则php-fpm进程数是动态的,最开始是pm.start_servers指定的数量,如果请求较多则会自动增加; 保证空闲的进程数不小于pm.min_spare_servers,如果进程数较多也会进行相应清理,保证多余的进程数不多于 pm.max_spare_servers。 这两种不同的进程管理方式,可以根据服务器的实际需求来进行调整。 这里先说一下涉及到这个的几个参数,他们分别是pm、pm.max_children、pm.start_servers、pm.min_spare_servers和pm.max_spare_servers; pm表示使用那种方式,有两个值可以选择,就是static(静态)或者dynamic(动态),在更老一些的版本中dynamic被称作apache-like; 这个要注意看配置文件的说明。下面4个参数的意思分别为:pm.max_children:静态方式下开启的php-fpm进程数量; pm.start_servers:动态方式下的起始php-fpm进程数量; pm.min_spare_servers:动态方式下的最小php-fpm进程数量; pm.max_spare_servers:动态方式下的最大php-fpm进程数量。 如果dm设置为static,那么其实只有pm.max_children这个参数生效,系统会开启设置数量的php-fpm进程; 如果dm设置为 dynamic,那么pm.max_children参数失效,后面3个参数生效; 系统会在php-fpm运行开始 的时候启动pm.start_servers个php-fpm进程,然后根据系统的需求动态; 在pm.min_spare_servers和 pm.max_spare_servers之间调整php-fpm进程数。 那么,对于我们的服务器,选择哪种执行方式比较好呢?事实上跟Apache一样,运行的PHP程序在执行完成后,或多或少会有内存泄露的问题; 这也是为什么开始的时候一个php-fpm进程只占用3M左右内存,运行一段时间后就会上升到20-30M的原因了。 对于内存大的服务器(比如8G以上)来说,指定静态的max_children实际上更为妥当,因为这样不需要进行额外的进程数目控制,会提高效率; 因为频繁开关php-fpm进程也会有时滞,所以内存够大的情况下开静态效果会更好; 数量也可以根据 内存/30M 得到,比如8GB内存可以设置为100,那么php-fpm耗费的内存就能控制在 2G-3G的样子; 如果内存稍微小点,比如1G,那么指定静态的进程数量更加有利于服务器的稳定,这样可以保证php-fpm只获取够用的内存; 将不多的 内存分配给其他应用去使用,会使系统的运行更加畅通。 对于小内存的服务器来说,比如256M内存的VPS,即使按照一个20M的内存量来算,10个php-cgi进程就将耗掉200M内存; 那系统的崩 溃就应该很正常了,因此应该尽量地控制php-fpm进程的数量,大体明确其他应用占用的内存后,给它指定一个静态的小数量; 会让系统更加平稳一些或者使用动态方式,因为动态方式会结束掉多余的进程,可以回收释放一些内存; 所以推荐在内存较少的服务器或VPS上使用具体最大数量根据 内存/20M 得到。 比如说512M的VPS,建议pm.max_spare_servers设置为20,至于pm.min_spare_servers,则建议根据服务器的负载情况来设置,比较合适的值在5~10之间. #update 20130210 512MB的VPS awk '! /^$|^;|^ /' /usr/local/php/etc/php-fpm.conf [global] pid = run/php-fpm.pid error_log = log/php-fpm.log ;log_level = notice emergency_restart_threshold = 10 emergency_restart_interval = 1m [www] user = www group = www listen = 127.0.0.1:9000 listen.owner = www listen.group = www listen.mode = 0666 pm = dynamic pm.max_children = 20 pm.start_servers = 5 pm.min_spare_servers = 5 pm.max_spare_servers = 15 pm.max_requests = 1024 slowlog = var/log/php-fpm.log.slow request_slowlog_timeout = 20 request_terminate_timeout = 60s rlimit_files = 65535 rlimit_core = 0 详细的php-fpm.conf 配置参数 FPM 配置文件为php-fpm.conf,其语法类似 php.ini 。 全局配置段([global]) pid string PID文件的位置. 默认为空. error_log string 错误日志的位置. 默认: 安装路径#INSTALL_PREFIX#/log/php-fpm.log. log_level string 错误级别. 可用级别为: alert(必须立即处理), error(错误情况), warning(警告情况), notice(一般重要信息), debug(调试信息). 默认: notice. emergency_restart_threshold int 如果子进程在emergency_restart_interval设定的时间内收到该参数设定次数的SIGSEGV 或者 SIGBUS退出信息号,则FPM会重新启动。 0 表示 '关闭该功能'. 默认值: 0 (关闭). emergency_restart_interval mixed emergency_restart_interval用于设定平滑重启的间隔时间. 这么做有助于解决加速器中共享内存的使用问题. 可用单位: s(秒), m(分), h(小时), 或者 d(天). 默认单位: s(秒). 默认值: 0 (关闭). process_control_timeout mixed 设置子进程接受主进程复用信号的超时时间. 可用单位: s(秒), m(分), h(小时), 或者 d(天) 默认单位: s(秒). 默认值: 0. daemonize boolean 设置FPM在后台运行. 设置 'no' 将 FPM 保持在前台运行用于调试. 默认值: yes. 运行配置区段([www]) 在FPM中,可以使用不同的设置来运行多个进程池。 这些设置可以针对每个进程池单独设置。 listen string 设置接受FastCGI请求的地址. 可用格式为: 'ip:port', 'port', '/path/to/unix/socket'. 每个进程池都需要设置. listen.backlog int 设置 listen(2) 的半连接队列长度. '-1' 表示无限制. 默认值: -1. listen.allowed_clients string 设置允许连接到FastCGI的服务器IPV4地址. 等同于PHP FastCGI (5.2.2+)中的 FCGI_WEB_SERVER_ADDRS环境变量. 仅对TCP监听起作用. 每个地址是用逗号分隔. 如果没有设置或者为空,则允许任何服务器请求连接. 默认值: any. listen.owner string 如果使用,表示设置Unix套接字的权限. 在Linux中,读写权限必须设置,以便用于WEB服务器连接. 在很多BSD派生的系统中可以忽略权限允许自由连接. 默认值: 运行所使用的用户合租, 权限为0666. listen.group string 参见 listen.owner. listen.mode string 参见 listen.owner. user string FPM 进程运行的Unix用户. 必须设置. group string FPM 进程运行的Unix用户组. 如果没有设置,则默认用户的组被使用. pm string 设置进程管理器如何管理子进程. 可用值: static, dynamic. 必须设置. static - 子进程的数量是固定的 (pm.max_children). dynamic - 子进程的数量在下面配置的基础上动态设置: pm.max_children, pm.start_servers, pm.min_spare_servers, pm.max_spare_servers. pm.max_children int 子进程的数量,pm 设置为 static 时表示创建的, pm 设置为 dynamic 时表示最大可创建的. 必须设置. 该选项设置可以同时提供服务的请求数限制. 类似 Apache 的 mpm_prefork 中 MaxClients 的设置和 普通PHP FastCGI中的 PHP_FCGI_CHILDREN 环境变量. pm.start_servers in 设置启动时创建的子进程数目. 仅在 pm 设置为 dynamic 时使用. 默认值: min_spare_servers + (max_spare_servers - min_spare_servers) / 2. pm.min_spare_servers int 设置空闲服务进程的最低数目. 仅在 pm 设置为 dynamic 时使用. 必须设置. pm.max_spare_servers int 设置空闲服务进程的最大数目. 仅在 pm 设置为 dynamic 时使用. 必须设置. pm.max_requests int 设置每个子进程重生之前服务的请求数. 对于可能存在内存泄漏的第三方模块来说是非常有用的. 如果设置为 '0' 则一直接受请求. 等同于 PHP_FCGI_MAX_REQUESTS 环境变量. 默认值: 0. pm.status_path string FPM状态页面的网址. 如果没有设置, 则无法访问状态页面. 默认值: none. ping.path string FPM监控页面的ping网址. 如果没有设置, 则无法访问ping页面. 该页面用于外部检测FPM是否存活并且可以响应请求. 请注意必须以斜线开头 (/). ping.response string 用于定义ping请求的返回相应. 返回为 HTTP 200 的 text/plain 格式文本. 默认值: pong. request_terminate_timeout mixed 设置单个请求的超时中止时间. 该选项可能会对php.ini设置中的'max_execution_time'因为某些特殊原因没有中止运行的脚本有用. 设置为 '0' 表示 'Off'. Available units: s(econds)(default), m(inutes), h(ours), or d(ays). Default value: 0. request_slowlog_timeout mixed 当一个请求该设置的超时时间后,就会将对应的PHP调用堆栈信息完整写入到慢日志中. 设置为 '0' 表示 'Off'. 可用单位: s(秒)(默认), m(分), h(小时), 或者 d(天). 默认值: 0. slowlog string 慢请求的记录日志. 默认值: #INSTALL_PREFIX#/log/php-fpm.log.slow. rlimit_files int 设置文件打开描述符的rlimit限制. 默认值: 系统定义值. rlimit_core int 设置核心rlimit最大限制值. 可用值: 'unlimited' 、0或者正整数. 默认值: 系统定义值. chroot string 启动时的Chroot目录. 所定义的目录需要是绝对路径. 如果没有设置, 则chroot不被使用. chdir string 设置启动目录,启动时会自动Chdir到该目录. 所定义的目录需要是绝对路径. 默认值: 当前目录,或者/目录(chroot时). catch_workers_output boolean 重定向运行过程中的stdout和stderr到主要的错误日志文件中. 如果没有设置, stdout 和 stderr 将会根据FastCGI的规则被重定向到 /dev/null . 默认值: 空. 注意: request_terminate_timeout = 30 #表示等待30秒后,结束那些没有自动结束的php脚本,以释放占用的资源。php.ini里面的max_execution_time 也需要调整 结束 更多请: linux 相关 37275208 vmware 虚拟化相关 166682360 本文转自 dongnan 51CTO博客,原文链接:http://blog.51cto.com/dngood/947595
D11-Nginx-Upgrade 有两种情况下需要升级Nginx: 1 要升级到Nginx 的新版本 2 要为Nginx 添加新的模块 1 查看Nginx版本 与 配置参数 /usr/local/nginx/sbin/nginx -V nginx version: nginx/0.8.52 built by gcc 4.1.2 20080704 (Red Hat 4.1.2-46)TLS SNI support disabled configure arguments: --user=www --group=www --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module --with-http_flv_module --with-http_gzip_static_module --http-client-body-temp-path=/var/tmp/nginx/client --http-proxy-temp-path=/var/tmp/nginx/proxy --http-fastcgi-temp-path=/var/tmp/nginx/fcgi 2 关闭Nginx /usr/local/nginx/sbin/nginx -s stop 3 升级新版本Nginx tar zxf nginx-1.2.3.tar.gz cd nginx-1.2.3 ./configure --prefix=/usr/local/nginx --with-pcre=../pcre-8.12/ --with-openssl=/usr/local/openssl/ --with-http_ssl_module --with-http_flv_module --with-http_gzip_static_module --user=www --group=www make 注意:没有make install4 备份 cp /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.old cp /root/nginx-1.2.3/objs/nginx /usr/local/nginx/sbin/ cp: overwrite `/usr/local/nginx/sbin/nginx'? y 注意:旧版本(sbin/nginx)仍可使用5 测试 /usr/local/nginx/sbin/nginx -t nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful /usr/local/nginx/sbin/nginx -V nginx version: nginx/1.2.3 built by gcc 4.1.2 20080704 (Red Hat 4.1.2-46)TLS SNI support enabled configure arguments: --prefix=/usr/local/nginx --with-pcre=../pcre-8.12/ --with-openssl=/usr/local/openssl/ --with-http_ssl_module --with-http_flv_module --with-http_gzip_static_module --user=www --group=www6 比较 du -sh * 6.2M nginx4.3M nginx.old7 启动nginx /usr/local/nginx/sbin/nginx 参考平滑升级你的Nginx PS: 这里未能实现nginx 在线升级。 #update 20121221 stub_status模块 Nginx中的stub_status模块主要用于查看Nginx的一些状态信息, 如果你要使用stub_status模块模块,则要在编译安装Nginx时指定,或者添加. 查看Nginx版本 与 配置参数 nginx -V nginx version: nginx/1.2.3 built by gcc 4.1.2 20080704 (Red Hat 4.1.2-46) TLS SNI support enabled configure arguments: --prefix=/usr/local/nginx --with-pcre=../pcre-8.12/ --with-openssl=/usr/local/openssl/ --with-http_ssl_module --with-http_flv_module --with-http_gzip_static_module --user=www --group=www 配置并编译 tar zxf nginx-1.2.3.tar.gz tar zxf pcre-8.12.tar.gz ./configure --prefix=/usr/local/nginx --with-pcre=../pcre-8.12/ --with-openssl=/usr/local/openssl/ --with-http_ssl_module --with-http_flv_module --with-http_gzip_static_module --user=www --group=www --with-http_stub_status_module make 注意:没有make install 备份 nginx -s stop cp /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.old.2 cp /root/nginx-1.2.3/objs/nginx /usr/local/nginx/sbin/ cp: overwrite `/usr/local/nginx/sbin/nginx'? y 测试 /usr/local/nginx/sbin/nginx -t nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful /usr/local/nginx/sbin/nginx -V nginx version: nginx/1.2.3 built by gcc 4.1.2 20080704 (Red Hat 4.1.2-46) TLS SNI support enabled configure arguments: --prefix=/usr/local/nginx --with-pcre=../pcre-8.12/ --with-openssl=/usr/local/openssl/ --with-http_ssl_module --with-http_flv_module --with-http_gzip_static_module --user=www --group=www --with-http_stub_status_module 配置 vim /usr/local/nginx/conf/vhosts/www.test.com location /nginx-status { auth_basic "NginxStatus"; allow 192.168.4.35; deny all; stub_status on; access_log on; } nginx -t nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful nginx 结束 更多请: linux 相关 37275208vmware 虚拟化相关 166682360 本文转自 dongnan 51CTO博客,原文链接:http://blog.51cto.com/dngood/1017670
制作 ESXi 5.1 的USB闪存"引导安装"盘 1 准备工作 linux 系统 //我这里是ubuntu 12.04 U盘一个 //8GB kingston ESXi ISO文件 //vmware 官网下载 VMware-VMvisor-Installer-5.1.0-799733.x86_64.iso,XXXXXX为内部版本号2. 为U盘创建分区表 fdisk /dev/sdb "d" 删除全部分区 "n" 创建遍及整个磁盘的主分区1 "t" 设置文件系统为FAT32(LBA),代码为"c" "a" 设置主分区1的Boot标记 "p" 打印分区表 结果应类似下表: Disk /dev/sdb: 8076 MB, 80761322352 bytes 186 heads, 28 sectors/track, 3028 cylinders Units = cylinders of 5208 * 512 = 2666496 bytes Device Boot Start End Blocks Id System /dev/sdb1 * 1 3029 7885824 c W95 FAT32 (LBA) "w" 写入分区表并退出注意:如有疑问可以参考最后的 fdisk 详细过程。3. 使用FAT32文件系统格式化U盘 mkfs.vfat -F 32 -n ESXi /dev/sdb1 4. 安装syslinux并写入MBR syslinux /dev/sdb1 cat /usr/lib/syslinux/mbr.bin > /dev/sdb 5. 挂载U盘 mount /dev/sdb1 /mnt/usb 6. 挂载ESXi安装程序ISO镜像 mount -o loop VMware-VMvisor-Installer-5.1.0-799733.x86_64.iso /mnt/iso 7. 将ISO镜像的内容复制到U盘 cp -r /mnt/iso/* /mnt/usb/ 8. 将isolinux.cfg文件重命名为syslinux.cfg mv /mnt/usb/isolinux.cfg /mnt/usb/syslinux.cfg 9. 编辑syslinux.cfg 文件 vim /mnt/usb/syslinux.cfg 在/mnt/usb/syslinux.cfg 文件中,将APPEND -c boot.cfg 一行更改为 APPEND -c boot.cfg -p 1。 10. 拷贝一个新的menu.c32文件到U盘,覆盖原来的文件 cp /usr/lib/syslinux/menu.c32 /mnt/usb/ 注意:这步并不在VMware vSphere官方手册 中,如没有此步骤,引导时会出现“menu.c32: not a COM32R image”这样的错误。11. 卸载U盘 umount /mnt/usb12. 卸载ISO镜像 umount /mnt/iso完工:现在U盘可以引导安装ESXi 5.1 了fdisk 详细过程,注意红色字 fdisk /dev/sdb Command (m for help): p Disk /dev/sdb: 8166 MB, 8166703104 bytes 64 heads, 32 sectors/track, 7788 cylinders, total 15950592 sectors Units = sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disk identifier: 0x4bd294d1 Device Boot Start End Blocks Id System/dev/sdb1 * 0 3311615 1655808 17 Hidden HPFS/NTFS Command (m for help): d Selected partition 1 Command (m for help): n Partition type: p primary (0 primary, 0 extended, 4 free) e extended Select (default p): p Partition number (1-4, default 1): 1 First sector (2048-15950591, default 2048): Using default value 2048 Last sector, +sectors or +size{K,M,G} (2048-15950591, default 15950591): Using default value 15950591 Command (m for help): t Selected partition 1 Hex code (type L to list codes): c Changed system type of partition 1 to c (W95 FAT32 (LBA)) Command (m for help): a Partition number (1-4): 1 Command (m for help): p Disk /dev/sdb: 8166 MB, 8166703104 bytes 64 heads, 32 sectors/track, 7788 cylinders, total 15950592 sectors Units = sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disk identifier: 0x4bd294d1 Device Boot Start End Blocks Id System/dev/sdb1 * 2048 15950591 7974272 c W95 FAT32 (LBA) Command (m for help): w The partition table has been altered! Calling ioctl() to re-read partition table. WARNING: If you have created or modified any DOS 6.x partitions, please see the fdisk manual page for additional information. Syncing disks. 参考 VMware vSphere官方手册制作 ESXi 5.0 的 USB 安装盘 结束 更多请: linux 相关 37275208 vmware 虚拟化相关 166682360 本文转自 dongnan 51CTO博客,原文链接:http://blog.51cto.com/dngood/1040268
如何使用你手中的利器 由于很多童鞋拥有了利器却不会使用,出现了无法访问部分网站的情况。小鸟特地抽空来写一篇攻略。使用到的利器为 Firefox8 + Bitvise Tunnelier。为什么选择火狐浏览器?因为他有利用远程服务器的DNS功能,能有效避开国内的DNS污染。我猜你现在已经下载好了这两样利器把,现在我们先来打开他的远程DNS功能(默认是关闭的)。 1:在浏览器地址栏输入about:config 回车,会出现个警告,咱们点确定后,在过滤器里输入remote后出现的network.proxy.socks_remote_dns就是我们要的功能了,双击它,使值变成True就行。接着设置firefox的代理部分。 步骤1 2:点左上橘黄色标志,选择选项-&gt;选项。然后选择高级-&gt;网络-&gt;配置。选择手动配置代理后,删除HTTP,SSL,FTP代理栏里的ip地址,修改socks主机的端口为8888后确定。到这里firefox的设置已经全部完成,剩下的就是Bitvise Tunnelier的设置了。 步骤2-1 步骤2-2 3:打开Bitvise Tunnelier,Host填写ip信息,Port填写端口信息,并且输入好Username和Password。切换到Options页面,去掉右边的Open Terminal和Open SFTP前面的勾。接着去Service页面,Socks / HTTP Proxy Forwarding下面的框打上钩, Listen Port输入8888。到此所有配置已经完毕。 步骤3-1 步骤3-2 点击程序最左下的Login后会有提示出来,让你保存key,选择最左边的后,下面的信息返回了类似Initializing SOCKS / HTTP CONNECT proxy on 127.0.0.1:8888 succeeded.的信息就说明成功了。然后用firefox访问ip138.com看看自己的ip是否变了,如果变了就说明成功连上代理了,可以访问你想要访问的一切网站。enjoy it! 另外由于这是最基础的使用方法,所以所有用firefox访问的网站都会走代理,访问国内的某些网站只有更慢,可以使用firefox的插件autoproxy来避免此现象,有空我再写一篇高级应用的介绍文吧。ok,这次的介绍就到这吧,希望大家喜欢。 本文转自 烂泥行天下 51CTO博客,原文链接:http://blog.51cto.com/ilanni/799401
本文首发于烂泥行天下,由秀依林枫提供友情赞助 四、Domino的搭建与配置 1、 Domino Server及其相关软件的安装 我们现在以Domino 8.5.2 32bit为例进行测试。开始Domino的安装。 软件许可协议 程序安装目录 数据安装目录 选择安装类型 确认安装 安装完成 以上是Domino Server的安装,下面我们就开始语言包的安装。语言包的安装和Domino Server安装基本上差多,我在此只把需要注意的重点截图出来。 在这一步的时候,一定要选择“替换Language Pack”,而不是“将Language Pack添加到Domino服务器”。 语言包安装完毕后,我们就要Domino客户端。Domino客户端与Domino Server的安装也是基本一样的,但是在选择安装Domino组件时,一定要选择“Domino Administrator”组件。因为该组件中包含Domino与AD的同步工具“ADSync”。如下图: 其他的一路“下一步”即可。 2、 Domino Server的配置 Domino所需要的软件安装完毕后,我们就要初始化Domino Server。双击启动桌面的Lotus Domino Server图标。如下图: 启动Domino Server后系统会弹出欢迎界面,我们只需点击“Next”即可。 我们选择第一项“设置第一台服务器” “Server name”为服务器名称,“Server title”为服务器标题 设置组织机构名称 设置网络Domino的网络域名 设置管理员的用户名及密码 设置Domino要开启的服务,我们现在开启了HTTP服务、邮件服务、LDAP服务。 设置Domino的网络域 下边直接下一步,即可完成配置。配置完成后,我们需要使用Domino Administrator客户端来对Domino Server服务器进行设置。打开桌面上的Domino Server快捷方式。 在弹出的界面中输入,相应的帐户名和服务器地址,如下图: 在“Domino服务器名称”选项中,我们可以按照上述的形式填写。也可以直接填写Domino服务器的IP地址。此时会提示你,该用户的ID文件存放位置。然后会提示你输入相应的密码,此密码就是Domino管理员的密码。 进入Domino Administrator的界面如下: 现在我们开始修改服务器的配置文档。点击“配置”—“服务器”—“当前服务器配置文档”: 在“基本”中,标准的Internet主机名:mail.broada.cc,启用“SMTP侦听任务”。而在“端口”—“Internet端口”—“邮件”中“邮件SMTP外来”中“名称和口令”和“匿名”选择是,如下图: 在“消息处理”—“域”—“添加域”,新建“全球网络域”: 然后再“转换”—“本地主internet网络域”中填写“broada.cc”: 至此Domino邮件服务器基本配置已经完成,接下来我们测试一下,能否正常发收邮件。 我们首先注册一个用户,点击“配置”—“注册”—“个人”: 此时会弹出一个“选择验证者”的窗口。我们选择“验证者标识”,找到“cert.id”文件即可。注意此文件存放在Domino的副安装目录下。如下图: 然后输入管理员的密码,即可: 在接下来的界面中,我们输入要注册人的相关信息即可。 注意在注册用户时,“姓”选项栏是一定要填写的。其相应的邮件地址也会自动生成,如下图: 3、 Domino邮件收发测试 注册完毕用户后,我们登录此账户然后给自己发一份邮件看看如何。 现在可以看到,此时Domino已经可以正常发送和接收邮件了。 一、Domino与AD的集成 1、 AD与Domino集成的方式 AD与Domino的集成方式是利用Domino的Directory Assistance数据库连接AD目录服务器,也就是把AD中数据导入到Domino中。 2、 Domino上需要做的配置 要进行正确的AD集成,我们要在Domino要先新建一条策略。“配置”—“策略”—“新建”,如下图: 点击“新建”选项,配置相应的策略。 选择邮件服务器,这个地方一定要操作,要不然在AD同步时,会报错的。然后确认保存即可。 配置完成后的策略,如上图。 策略配置完毕后,我们就要使用Domino的LDAP目录服务了。 注意Domino的LDAP服务使用的端口号是389,而AD活动目录也是使用389端口的。所以我们需要修改Domino的LDAP服务器端口号。如下图: Domino的LDAP端口号修改完毕后,我们就要配置LDAP。点击“配置”—“目录”—“LDAP”—“设置”。 如果是第一次进行该操作,系统将提示缺少文档配置,点击【确定】按钮进入文档设置状态。在文档内使用默认设置后,保存退出即可。 接下来,我们要建立相应的数据库。打开“文件”—“应用程序”—“新建”,如下图: 在弹出的窗口中填入相应的信息,“模版”一定要选择“Directory Assistance”: 上图中黄色部分标记出来的“文件名:AD.nsf”一定要记住。等下配置的时候,我们会使用到的。 点击“确定“,出现如下的界面: 我们点击“Add Directory Assistance”来添加一个目录数据库。在“Domain type”中一定要选择“LDAP”,其他的按照如下图的选择即可。 在LDAP标签页,我们要需要注意的内容如下: 在该页签中,hostname域中需填写AD主机服务器地址,并在IP后添加389端口标志。例如:oadminis-668fc8.broada.cc:289 在username和password域中均需要正确填写AD主机中所存在的administrator账户格式与密码。例如:cn=administrator,cn=users,dc=broada,dc=cc 在Base DN for search域中需要正确填写AD中的DN搜索格式。例如:dc=broada,dc=cc 在Channel encryption域后,选择None,并确认端口为389。注意此操作一定要先于其他几项操作,保存后在操作其他的配置。 点击“Verify”验证是否能成功连接AD,如下图: 以上配置完毕后,我们先来测试LDAP是否正常工作。启动outlook express,点击“工具”—“账户”—“添加”—“目录服务”,如下图: 输入LDAp的目录服务器地址,然后按照操作。如下图: 然后我们再次返回,修改LDAP的端口号,如下图: 然后我们点击“查找”—“个人”,在“搜索范围”中选择我们的LDAP服务器,如下图: 通过上图,我们可以看到Domino的LDAP目录服务已经可以正常工作并使用了。 有关Domino的设置,到此结束。下面我们就需要在AD上进行相关的设置。 3、 AD上需要做的配置 我们需要在AD上所进行的相关配置,打开Domino Administrator所在的目录。如下图: 打开命令提示符。键入: 此时将出现一个消息框,指出注册已完成。 此时,我们打开“Active Directory 用户和计算机”会发现,在下面多了“Lotus Domino选项”,如下图: 右键右侧的“Domino目录同步”,选择“选项”,在弹出的对话框中输入Domino管理员的密码。 第一次输入密码时,会提示你出错。此时会让你选择“Domino的服务器”: 服务器不能选择本地,要选择网络服务器。然后系统会提示你,正在“初始化Lotus ADSync”。 初始化完毕后,如下图: ADSync初始化完毕后,我们来看看其相关的配置: 4、 AD与Domino同步测试 以上配置完毕AD与Domino后,我们现在来测试AD与Domino的账户同步。 在AD中新建一个用户,如下图: AD中的用户已经添加完毕了,上图中也已经提示该用户已经同步到Domino中了。我们现在来看看Domino中是否真的同步进来了。 打开Domino,“个人和组”— “个人”,如下图: 根据上图,我们很轻易的看到AD中的“test”用户已经同步进来了,而且我们可以看到此用户是没有邮件地址的。我们现在在AD中进行个人信息的修改,如下图: 此时我们再来看看Domino此用户逇邮件地址是否存在。 可以看到现在用户test的邮件地址已经同步过来了。 到此AD与Domino同步已经全部配置完毕。 本文转自 烂泥行天下 51CTO博客,原文链接:http://blog.51cto.com/ilanni/1171401
本文由男装世家提供友情赞助,首发于烂泥行天下。 今天本机Win8系统使用公司产品,在命令行SQLPlus下连接Oracle数据库时,却提示如下错误信息: SP2-1503: 无法初始化Oracle调用界面 SP2-0152: ORACLE 不能正常工作 经过百度google得知,是SQLPlus运行必须是管理员权限。而win8下,我们进行如下操作: 找到Oracle安装目录中BIN目录下sqlplus.exe。右键--属性--兼容性-选中以管理员身份运行--确认即可,如下图: 如此操作完毕后,再在命令行下执行SQLPlus就不会报错了。 本文转自 烂泥行天下 51CTO博客,原文链接:http://blog.51cto.com/ilanni/1344765
本文首发于烂泥行天下。 最近一段时间,一直在学习有关Nagios监控系统的相关知识。 有关Nagios监控系统,你可以在百度或者google搜索下,那文章是一堆一堆的。让人看起来很简单。但是在实际的搭建过程中,却不是那么回事。下面就把自己在搭建过程的步骤及注意的事项记录下来。 在安装Nagios前,有些软件与套件需要首先安装。具体如下: PHP、Apache、Net-snmp、gcc、perl-CPAN 其中Apache是nagios打开必须要使用的。因为Nagios监控主要是通过插件来实现的,而插件有包括SNMP方式、NRPE方式。在接下来的几篇文章,都是围绕SNMP方式来进行监测。所以需要安装net-snmp相关组件。 而SNMP方式监测都是通过check_snmp_mem.pl等perl文件来实现的,所以在安装SNMP相关的插件时,需要perl-CPAN的支持。所以需要安装perl-CPAN。 有关perl-CPAN的安装,可以参考我的另外一篇文章《烂泥:perl中CPAN的安装》。 首先,我们来安装相关的软件及套件。我们可以通过yum方式安装,也可以通过编译方式来。因为牵涉的软件及套件比较多,各个软件集套件的依赖比较麻烦,所以建议使用yum方式来安装。 本次实验OS:CentOS 6.6 mini 32bit Nagios版本是中文版:nagios-cn 本次相关的软件可以到这个地址下载: http://pan.baidu.com/s/1jGzFtiQ nagios的运行是在nagios用户下进行的,所以在此之前我们要创建nagios。如下: useradd nagios id nagios 下面我们来使用yum方式安装,如下图: yum -y install php httpd net-snmp gcc perl-CPAN 安装完毕后,我们把Nagios的相关软件包上传到Linux服务器上。 具体如何上传,这个我就在此作介绍了。你可以通过FTP、SSH等等都可以,就看你自己喜欢的方式了。 上传完毕后,我们来进行解压。我现在把相关的软件包都放在/home/ilanni目录下,如下图: tar -xf nagios-cn-3.2.0.tar.bz2 tar -xf nagios-plugins-2.0.1.tar.gz tar -xf nagios-snmp-plugins.1.1.1.tgz 解压完毕后,我们来进入nagios-cn-3.2.0目录,如下图: 开始编译nagios,如下图: ./configure --prefix=/usr/local/nagios --nagios的安装路径 编译完毕,如下图: 可以看到需要新建用户nagios,系统中如果没有的话。我们现在可以新建用户,如下图: Nagios用户新建完毕后,我们还继续nagios编译后的工作。 继续执行make all ,如下图: make all完毕后,如下图: 我们只需要按照上边的命令执行即可,如下图: make install安装nagios的相关程序文件。 make install-init安装nagios启动的初始化脚本。 make install-commandmode 安装nagios的命令文件。 make install-config安装nagios的配置文件。 make install-webconf安装nagios的web配置文件。 以上是nagios的安装步骤,下面进行nagios插件的安装。 进入nagios的插件目录,如下图: [root@ilanni nagios-cn-3.2.0]# cd ../nagios-plugins-2.0.1 [root@ilanni nagios-plugins-2.0.1]# pwd /home/ilanni/nagios-plugins-2.0.1 [root@ilanni nagios-plugins-2.0.1]# ll 编译插件 ./configure --prefix=/usr/local/nagios/ 编译完毕,没有报错就可以进行安装。 make make install Nagios与nagios插件基本安装完毕,我们可以查看下。 插件截图: 如果你仔细看的话,会发现这个插件时没有有关SNMP的。如下图: 下面我们就安装SNMP的插件。切换到nagios_plugins目录,如下图: 注意SNMP安装之前一定要安装CPAN。有关CPAN的安装,我在文章开头就说过,可以参考我的另外一篇文章《烂泥:perl中CPAN的安装》。 执行install.sh进行安装,如下图: 接下来一路回车即可。 安装完毕如下图示: 现在SNMP的插件已经安装完毕,我们来查看下: 查看命令是否可以使用: 通过上图可以看到,snmp插件已经可以正常使用。 下面我们把nagios加入到系统的服务中,如下: chkconfig --add nagios chkconfig nagios on chkconfig --list nagios 在开始启动nagios之前,我们还要为nagios配置登录的用户名和密码。 有关nagios登录的用户名和密码,我们可以查看nagios.conf文件,如下: cat nagios.conf |grep -v ^#|grep -v ^$ 通过上图,我们可以很明显看出nagios用户存放在/usr/local/nagios/etc/htpasswd.users文件中。 但是如果此时查看htpasswd.users文件会发现该文件是不存在的。 为什么回是这样呢? 这个是因为nagios安装完毕后,需要使用apache的htpasswd工具创建nagios登录的用户。如下: /usr/local/apache2/bin/htpasswd-c /usr/local/nagios/etc/htpasswd.users nagiosadmin 通过上图,我们可以很明显的看出,htpasswd在创建nagios登录用户的同时,也设置了该用户的密码。 注意:nagios默认的用户名是nagiosadmin。我们可以通过查看/usr/local/nagios/etc/cgi.conf文件得知。如下: cat cgi.cfg |grep -v^#|grep -v ^$ 现在我们再来查看htpasswd.users文件,内容如下: cat /usr/local/nagios/etc/htpasswd.users nagios用户创建完毕后,我们来启动nagios并登录,如下: /etc/init.d/nagios start ps aux |grep nagios 以上安装的nagios中文版,nagios最新版的安装和这个步骤基本一直。 这个是nagios4.1版本的界面。 nagios4.1的下载地址如下: http://www.nagios.org/download/core/thanks/?t=1426844202 wgethttp://prdownloads.sourceforge.net/sourceforge/nagios/nagios-4.1.0rc1.tar.gz 至此Nagios的安装已经结束,下篇我们来介绍Nagios的相关配置。 本文转自 烂泥行天下 51CTO博客,原文链接:http://blog.51cto.com/ilanni/1416723
本文首发于烂泥行天下。 IE10浏览器:appName:Microsoft Internet Explorer|-----|appCodeName:Mozilla|-----|userAgent:Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; InfoPath.2; .NET4.0C; .NET4.0E) 360浏览器:appName:Microsoft Internet Explorer|-----|appCodeName:Mozilla|-----|userAgent:Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; InfoPath.2; .NET4.0C; .NET4.0E) 360极速浏览器:appName:Microsoft Internet Explorer|-----|appCodeName:Mozilla|-----|userAgent:Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; InfoPath.2; .NET4.0C; .NET4.0E) 搜狗浏览器:appName:Microsoft Internet Explorer|-----|appCodeName:Mozilla|-----|userAgent:Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; InfoPath.2; .NET4.0C; .NET4.0E; SE 2.X MetaSr 1.0) ##MetaSr windows下的safar :appName:Netscape|-----|appCodeName:Mozilla|-----|userAgent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/534.57.2 (KHTML, like Gecko) Version/5.1.7 Safari/534.57.2 (safari在windows下已经停止开发了,也就是苹果已经抛弃windows下的浏览器市场了,在windows系统下用safari的用户也算得上奇葩了吧!) mac下的safari:appName:Netscape|-----|appCodeName:Mozilla|-----|userAgent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_4) AppleWebKit/536.30.1 (KHTML, like Gecko) Version/6.0.5 Safari/536.30.1 &#160; ##Safari 必须先检测chrome,猎豹,遨游等 chrome浏览器:appName:Netscape|-----|appCodeName:Mozilla|-----|userAgent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.94 Safari/537.36 ##Chrome 必须先检测猎豹遨游等 遨游浏览器:appName:Netscape|-----|appCodeName:Mozilla|-----|userAgent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Maxthon/4.0.6.2000 Chrome/26.0.1410.43 Safari/537.1 ##Maxthon QQ浏览器:appName:Microsoft Internet Explorer|-----|appCodeName:Mozilla|-----|userAgent:Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; InfoPath.2; .NET4.0C; .NET4.0E; QQBrowser/7.3.9825.400) ##QQBrowser fireFox 浏览器:appName:Netscape|-----|appCodeName:Mozilla|-----|userAgent:Mozilla/5.0 (Windows NT 6.1; WOW64; rv:21.0) Gecko/20100101 Firefox/21.0 ## 猎豹浏览器:appName:Netscape|-----|appCodeName:Mozilla|-----|userAgent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1180.92 Safari/537.1 LBBROWSER ##LBBROWSER 百度浏览器:appName:Microsoft Internet Explorer|-----|appCodeName:Mozilla|-----|userAgent:Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0; BIDUBrowser 2.x) ##BIDUBrowser 淘宝浏览器:appName:Netscape|-----|appCodeName:Mozilla|-----|userAgent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.11 (KHTML, like Gecko) Chrome/20.0.1132.11 TaoBrowser/3.0 Safari/536.11 ##TaoBrowser 关于浏览器识别的代码 function setIntestineBrowser(){ var userAgent = navigator.userAgent; var browserKeyArr = [{ name:'搜狗', domKey:'sougou', agentKey:'MetaSr' },{ name:'QQ', domKey:'qq', agentKey:'QQBrowser' }, { name:'猎豹', domKey:'liebao', agentKey:'LBBROWSER' },{ name:'淘宝', domKey:'taobao', agentKey:'TaoBrowser' },{ name:'遨游', domKey:'aoyou', agentKey:'Maxthon' }]; for(var i = 0,length = browserKeyArr.length; i < length ; i++){ var pattern = new RegExp(browserKeyArr[i].agentKey); if(pattern.test(userAgent)){ $('.collection-menu ul li[data-v=' + browserKeyArr[i].domKey + ']').click(); return ; } } } 补充说明:由于国内浏览器用的内核多是国外的,所以很多特性无法与国外浏览器区分,所以要先检测国外浏览器,再检测国内浏览器。这样当国内浏览器没有找到匹配项时就是内核默认的国外浏览器。 本文转自 烂泥行天下 51CTO博客,原文链接:http://blog.51cto.com/ilanni/1423500
本文首发于烂泥行天下。 由于工作需要公司最近的一台服务器需要开启启用FTP服务,用来传输文件。 但是考虑到该服务器是在公网,基于安全的考虑一般都是要开启防火墙的。而公司内部的FTP服务器,一般情况下我都是关闭防火墙的。 下面我就将有关防火墙的配置流出如下: OS:windows server 2003、2008 FTP:Filezilla Server 0.9.41 首先是安装FTP服务器,在此我使用时开源FTP服务器Filezill Server。有关Filezilla Server的安装与使用,你可以去百度,网上的文章比较多。在此我就不多介绍。 FTP协议的传输比较特别,不像其他协议使用一个端口。FTP协议需要使用两个端口,一个是21号端口,用来传输相关的命令。一个是数据端口,默认是20端口,用来传输文件数据。 所以我们需要在防火墙上开放两个端口21和20端口。 毕竟是公网传输,所以我们不得不考虑到安全,在此我们把FTP对应的端口修改为2121和6650。除此之外,我们还限制只有指定的IP地址才能连接FTP服务器。 如下图: 现在防火墙是开启状态,我们先来远程连接下。 可以看到无法连接FTP服务器。 现在我们在防火墙上开放2121和6650端口,如下: 现在我们在此连接FTP服务器,如下图: 通过上图可以看到,目前FTP客户端已经成功连接FTP服务器。 以上防火墙是在windows server 2003 上进行操作的,下面我们来看看windows server 2008上的防火墙设置。 在防火墙的规则选项中,我们只需要配置入站规则即可。如下图: 在入站规则中,以同样的方法开放6650端口。 以上是有关如何在防火墙上开放相应的端口,下面我们来配置指定的IP地址来连接FTP服务器。 其实有两种方法我们来指定IP地址来连接FTP服务器,一种是在Filezilla Server上进行设置,另外一种就是我们本文的重点防火墙。 首先,我们来看看Filezilla Server上边如何设置。打开Filezilla Server选择全局配置项,其中IP Filter是非常重要的。 IP Filter中上半部分填入禁止连接的IP地址,下半部分允许连接FTP服务器的IP地址。在此我们默认是所有的IP都不能连接FTP服务器,所以上半部分我们填入“*”。如下图: 现在我们来连接试试,我本地的公网IP为: 通过上图可以我本地是无法连接FTP服务器的。那么被允许的IP地址能不能连接呢?如下图: 可以很明显的看到是可以连接的。 以上是Filezilla Server本身有关IP地址过滤的设置。下面我们不使用Filezilla Server的设置,使用防火墙的设置。 打开防火墙配置的2121和6650端口选项,如下图: 点击“更改范围”—“自定义列表”,在自定义列表中填入允许访问的IP地址。如下图: 以上防火墙设置完毕后,我们再来连接测试。 可以看到我本地还是不能连接FTP服务器的,那么被允许的IP地址呢?如下图: 可以看到被允许的IP地址是可以连接FTP服务器的。 通过以上实验,我们可以知道。如果我们有特殊需要,比如开放服务器的80端口只能被指定的IP地址访问,这样就提高了相关应用程序的安全性。 特别是对于开放了3389端口的服务器,我们完全可以通过这种方法来降低服务器被攻击的可能性。 PS:Filezilla Server从0.9.42版本以后就不在支持windows Server 2003 操作系统。 本文转自 烂泥行天下 51CTO博客,原文链接:http://blog.51cto.com/ilanni/1434873
本文首发于烂泥行天下。 今天在启动virtualbox时,发现virtualbox报创建COM对象失败错误,如下图: 查找相关资料发现很有可能是virtualbox与OS不兼容造成。 调整virtualbox的兼容性,如下图: 然后再启动virtualbox,就可以了。 本文转自 烂泥行天下 51CTO博客,原文链接:http://blog.51cto.com/ilanni/1438516
本文首发于烂泥行天下。 公司服务器的虚拟化使用的是VM ESXi 5.0,为了更有效的利用服务器的硬盘空间。就把所有的镜像文件存放到另外一台linux服务器上,这样在使用vsphere安装虚拟机时可以直接使用linux服务器上的镜像文件,从而到达节省ESXi硬盘的空间的好处。 要达到这个目的,我们首先要在linux服务器上配置NFS网络文件系统。 本次实验linux OS:centos 6.4 64bit esxi:5.0 vsphere:5.0 NFS网络文件所需要的软件包包括:nfs-utils和rpcbind。 其中nfs-utils包提供了NFS服务器程序和相应的管理工具,而rpcbind是一个管理RPC连接的程序,rpcbind服务对NFS是必须的,因为它是NFS的动态端口分配守护进程,如果rpcbind不启动,NFS就是启动不了的。注意在centos5以前的版本使用的是portmap,centos6以后的版本使用的是rpcbind。 登录linux服务器,查询NFS相关的软件包。 yum list nfs* 直接安装nfs所需要的软件包: yum -y install nfs* 或者 yum –y install nfs-utils* 安装rpcbind软件包: yum -y install rpcbind 创建需要对外共享的目录: mkdir –p /data/work/soft/iso/ 以上操作完毕后,我们来配置NFS,编辑exports文件,输入一下内容: /data/work/soft/iso/ *(rw) 这条语句包括三部分内容: 需要共享的文件目录 *表示对所有用户 rw表示所有用户对此目录具有读写权限 注意exports配置文件是在rpcbind安装完毕后生成的,该文件所在位置为/etc/exports。 以上配置完毕后,我们需要先启动rpcbind服务,然后再启动nfs服务。 注意,此时我们没有考虑各种权限以及防火墙的问题。 NFS正常启动后,我们现在来配置vsphere。 打开vsphere连接esxi,如下图: 进入vsphere后,我们需要选择“配置”—“存储器”—“添加存储器”选择项,如下图: 存储器类型,我们要在此选择为“网络文件系统”,如下图: 在服务器选项中,填入NFS所在的服务器地址 文件夹选项中填入NFS的共享目录 数据存储名称选项中,可以自己自定义 如下图: 添加完毕后,我们就可以在存储器选项中看新加的NFS存储。如下图: 也可以浏览该NFS的内容: 我们也可以通过ssh连接esxi,查看到添加的NFS存储,如下图: 本文转自 烂泥行天下 51CTO博客,原文链接:http://blog.51cto.com/ilanni/1439945
在前一段时间,我写了几篇有关学习haproxy的文章。今天我们再来介绍下haproxy的https配置,https协议的好处在此,我们就不就作介绍了。 我们只介绍如何配置https,以及https在实际生产环境中的应用。 PS:本实验全部在haproxy1.5.4版本进行测试通过。haproxy1.3版本以下haproxy配置参数可能不能使用,需要注意版本号。 以下haproxy配置是线上生产环境直接使用的。 一、业务要求 现在根据业务的实际需要,有以下几种不同的需求。如下: 1.1 http跳转https 把所有请求http://http.ilanni.com的地址全部跳转为https//:http.ilanni.com这个地址。 1.2 http与https并存 服务器同时开放http://http.ilanni.com和https://http.ilanni.com的访问形式。 1.3 同台服务器不同域名之间的https与http 同一台服务器对http.ilanni.com域名访问的全部跳转为https://http.ilanni.com,而对haproxy.ilanni.com访问走http协议,也就是跳转到http://haproxy.ilanni.com这个地址。 1.4 同台服务器多域名均使用https 同一台服务器对http.ilanni.com和haproxy.ilanni.com访问走http是协议。 二、配置haproxy并测试业务需求 现在我们根据业务的需求,我们来配置haproxy一一达到其需求。 2.1 http跳转https配置 说实话haproxy的https配置要比nginx配置简单的多了,我们只需要加入几行代码即可实现https的功能。 http跳转https的haproxy配置文件内容,如下: global log 127.0.0.1 local0 log 127.0.0.1 local1 notice maxconn 4096 uid 188 gid 188 daemon tune.ssl.default-dh-param 2048 defaults log global mode http option httplog option dontlognull option http-server-close option forwardfor except 127.0.0.1 option redispatch retries 3 option redispatch maxconn 2000 timeout http-request 10s timeout queue 1m timeout connect 10s timeout client 1m timeout server 1m timeout http-keep-alive 10s timeout check 10s maxconn 3000 listen admin_stats bind 0.0.0.0:1080 mode http option httplog maxconn 10 stats refresh 30s stats uri /stats stats auth admin:admin stats hide-version frontend weblb bind *:80 acl is_http hdr_beg(host) http.ilanni.com redirect scheme https if !{ ssl_fc } bind *:443 ssl crt /etc/haproxy/ilanni.com.pem use_backend httpserver if is_http backend httpserver balance source server web1 127.0.0.1:7070 maxconn 1024 weight 3 check inter 2000 rise 2 fall 3 在以上配置文件中,需要注意的选项如下: tune.ssl.default-dh-param 2048因为我们的SSL密钥使用的是2048bit加密,所以在此进行声明。 acl is_http hdr_beg(host) http.ilanni.com redirect scheme https if !{ ssl_fc } bind *:443 ssl crt /etc/haproxy/ilanni.com.pem 这三行表示把所有访问http.ilanni.com这个域名的请求,全部转发到https://http.ilanni.com这个连接。 2.2 测试http跳转https http跳转https配置完毕后,我们选择来测试其跳转。如下: 你会发现在浏览器中,无论你输入的是http.ilanni.com,还是http://http.ilanni.com亦或是https://http.ilanni.com,都会自动跳转到https://http.ilanni.com。 这样就达到了,把所有的http请求跳转到https的目的。 2.3 http与https并存配置 haproxy要实现http和https并存的话,配置也很简单,只需要把haproxy分别监控不同的端口就行,配置文件如下: global log 127.0.0.1 local0 log 127.0.0.1 local1 notice maxconn 4096 user haproxy group haproxy daemon tune.ssl.default-dh-param 2048 defaults log global mode http option httplog option dontlognull retries 3 option redispatch maxconn 2000 timeout connect 5000ms timeout client 50000ms timeout server 50000ms listen admin_stats bind 0.0.0.0:1080 mode http option httplog maxconn 10 stats refresh 30s stats uri /stats stats auth admin:admin stats hide-version frontend weblb bind *:80 acl is_http hdr_beg(host) http.ilanni.com use_backend httpserver if is_http backend httpserver balance source server web1 127.0.0.1:7070 maxconn 1024 weight 3 check inter 2000 rise 2 fall 3 frontend weblb443 bind *:443 ssl crt /etc/haproxy/ilanni.com.pem acl is_443 hdr_beg(host) http.ilanni.com use_backend httpserver443 if is_443 backend httpserver443 balance source server web1 127.0.0.1:7070 maxconn 1024 weight 3 check inter 2000 rise 2 fall 3 在以上配置文件中,我们定义了两个前端,一个前端用于监听80端口,也就是http协议。另外一个前端监听443端口,也就是https协议。 此时haproxy会根据客户端请求的协议进行分发,如果发现客户端请求的是http协议,则把该请求分发到监听80端口的前端。如果发现客户端请求的是https协议,则把该请求分发到监听443端口的前端。如此就达到了haproxy让http和https并存的要求。 2.4 测试http与https并存 http与https并存配置完毕后,我们选择来测试其跳转。如下: 通过测试你会发现,在浏览器中如果你输入的是http://http.ilanni.com或者是http.ilanni.com都会直接跳转到http://http.ilanni.com,而输入的是https://http.ilanni.com,则只会跳转到https://http.ilanni.com。 如此就到达了,我们业务的要求实现http和https并存。 2.5 同台服务器不同域名之间的https与http配置 同台服务器不同域名之间的http和https配置比较复杂,第一需要监听两个端口,第二还要根据不同的域名进行分发。 haproxy配置文件如下: global log 127.0.0.1 local0 log 127.0.0.1 local1 notice maxconn 4096 uid 188 gid 188 daemon tune.ssl.default-dh-param 2048 defaults log global mode http option httplog option dontlognull option http-server-close option forwardfor except 127.0.0.1 option redispatch retries 3 option redispatch maxconn 2000 timeout http-request 10s timeout queue 1m timeout connect 10s timeout client 1m timeout server 1m timeout http-keep-alive 10s timeout check 10s maxconn 3000 listen admin_stats bind 0.0.0.0:1080 mode http option httplog maxconn 10 stats refresh 30s stats uri /stats stats auth admin:admin stats hide-version frontend weblb bind *:80 acl is_haproxy hdr_beg(host) haproxy.ilanni.com acl is_http hdr_beg(host) http.ilanni.com redirect prefix https://http.ilanni.com if is_http use_backend haproxyserver if is_haproxy backend haproxyserver balance source server web1 127.0.0.1:9090 maxconn 1024 weight 3 check inter 2000 rise 2 fall 3 frontend weblb443 bind *:443 ssl crt /etc/haproxy/ilanni.com.pem acl is_443 hdr_beg(host) http.ilanni.com use_backend httpserver443 if is_443 backend httpserver443 balance source server web1 127.0.0.1:7070 maxconn 1024 weight 3 check inter 2000 rise 2 fall 3 同台服务器不同域名之间的https与http配置,我们配置了两个前端一个用于监听80端口,并且根据不同的域名进行跳转。在80端口的规则中,如果客户端请求的是http.ilanni.com,这个域名的话,则haproxy会把该请求直接跳转到https://http.ilanni.com。如果是haproxy.ilanni.com,这个域名的话,则分发到后端的服务器。 另外一个前端用于监听443端口,用于分发客户端https://http.ilanni.com的请求。 2.6 测试同台服务器不同域名之间的https与http配置 同台服务器不同域名之间的https与http配置配置完毕后,我们现在来进行测试。如下: 通过上图,我们可以发现在浏览器中输入haproxy.ilanni.com会跳转到http://haproxy.ilanni.com这个地址,而如果输入的是http.ilanni.com或者是http://http.ilanni.com,亦或是https://http.ilanni.com的话,都会跳转到https://http.ilanni.com。 如此就达到了我们的业务要求,同台服务器上访问haproxy.ilanni.com直接跳转到80端口,如果访问的是http.ilanni.com域名的话则跳转到https://http.ilanni.com这个地址。 2.7 同台服务器多域名均使用https配置 要使同台服务器的两个设置多个域名都使用https协议的话,配置很简单。只需要在haproxy中启用各自的https配置即可。 haproxy配置文件,如下: global log 127.0.0.1 local0 log 127.0.0.1 local1 notice maxconn 4096 uid 108 gid 116 daemon tune.ssl.default-dh-param 2048 defaults log global mode http option httplog option dontlognull option http-server-close option forwardfor except 127.0.0.1 option redispatch retries 3 option redispatch timeout http-request 10s timeout queue 1m timeout connect 10s timeout client 1m timeout server 1m timeout http-keep-alive 10s timeout check 10s maxconn 3000 listen admin_stats bind 0.0.0.0:1080 mode http option httplog maxconn 10 stats refresh 30s stats uri /stats stats auth admin:admin stats hide-version frontend web80 bind *:80 acl is_http hdr_beg(host) http.ilanni.com redirect scheme https if !{ ssl_fc } bind *:443 ssl crt /etc/haproxy/ilanni.com.pem acl is_haproxy hdr_beg(host) haproxy.ilanni.com redirect scheme https if !{ ssl_fc } bind *:443 ssl crt /etc/haproxy/ilanni.com.pem use_backend httpserver if is_http use_backend haproxyserver if is_haproxy backend httpserver balance source server web1 127.0.0.1:6060 maxconn 1024 weight 3 check inter 2000 rise 2 fall 3 backend haproxyserver balance source server web1 127.0.0.1:9090 maxconn 1024 weight 3 check inter 2000 rise 2 fall 3 配置文件比较简单,在此就不做进一步的讲解了。 2.8 测试同台服务器多域名均使用https 同台服务器多域名均使用https,配置完毕后,现在我们来测试下。 通过上图,我们可以看到在浏览中无论是输入http.ilanni.com、http://http.ilanni.com,还是haproxy.ilanni.com、http://haproxy.ilanni.com,都会跳转到相应的https地址。 这也达到了我们业务的要求。 本文转自 烂泥行天下 51CTO博客,原文链接:http://blog.51cto.com/ilanni/1710201
这个月又快过完了,最近也比较忙,没时间写文章,今天挤点时间把zabbix3.0安装与配置的文章写下来。 其实zabbix3.0的安装很简单,但是由于个人比较懒,所以一直不喜欢使用源码方式进行安装,而且管理的服务器多了,源码安装也感觉不方便,所以现在大部分安装软件我都会首先选择yum或者apt-get方式进行。 本篇文章,我也不多介绍zabbix3.0安装的详细步骤了,只列出centos、ubuntu下zabbix3.0的相关安装命令以及zabbix的基本配置。 zabbix3.0对OS的要求:mysql5.0以上版本、apache1.3以上版本、php5.4以上版本。 注意:这个要求很重要。 一、zabbix server3.0在centos 7上安装 根据zabbix server3.0官方要求,目前zabbix server3.0在centos6 OS上不能进行yum安装。如果一定要在centos6 OS上进行安装zabbix server3.0的话,强烈建议通过源码方式进行编译安装,同时还需要注意PHP的版本。 考虑到这些因素,所以在此我们是在centos7 OS上进行yum安装zabbix server3.0。 注意:尽管zabbix server3.0在centos6 OS上不能yum方式进行安装,但是zabbix-agent3.0在centos6 OS上是可以进行yum安装的。 1.1 搭建lamp环境 在centos7上安装zabbix server3.0之前,我们首先搭建zabbix所需要的lamp环境。 下载最新的yum源,如下: wget -P /etc/yum.repos.d http://mirrors.aliyun.com/repo/Centos-7.repo 在开始安装之前,还需要说明下centos7自带的mysql是mariadb,我们可以通过如下命令查看: yum search mysql|tac 现在开始安装lamp环境,使用如下命令: yum -y install mariadb mariadb-server php php-mysql httpd 通过上图,我们可以很明显的看出centos7默认安装的是php5.4、httpd2.4和maradb5.5,这个完全符合zabbix3.0对软件版本的要求。 lamp安装完毕后,我们现在来配置mysql数据库。 设置开机自启动mysql,并启动mysql,使用如下命令: systemctl enable mariadb systemctl start mariadb 初始化mysql数据库,并配置root用户密码。使用如下命令: mysql_secure_installation 注意:在上图中的Enter current passwdord for root处,我们直接敲回车键即可。因为centos7上mysql的默认root用户密码为空。 上图中主要是为root用户配置密码,并刷新相关权限。 上图中主要是配置匿名用户、test用户以及root用户远程连接等相关配置。 mysql初始化完毕后,我们现在来创建zabbix数据库及其用户,使用如下命令: mysql -uroot -p'ilanni' -e "create database zabbix default character set utf8 collate utf8_bin;" mysql -uroot -p'ilanni' -e "grant all on zabbix.* to 'zabbix'@'%' identified by 'zabbix';" 现在来测试刚刚创建的zabbix用户,是否可以连接mysql数据库,如下: mysql -uzabbix -pzabbix show databases; 通过上图,我们可以很明显的看出zabbix用户是可以正常连接数据库的。 启动apache以及开放80端口,如下: systemctl start httpd netstat –tunl firewall-cmd --zone=public --add-port=80/tcp –permanent firewall-cmd --reload 注意:centos7的防火墙和centos6的防火墙很不一样。 到此lamp环境已经全部搭建完毕。 1.2 安装zabbix server3.0 lamp环境搭建完毕后,我们现在开始正式安装zabbix3.0。 安装zabbix3.0所需要EPEL源和zabbix的yum源,如下: rpm -ivh http://mirrors.aliyun.com/epel/7/x86_64/e/epel-release-7-6.noarch.rpm rpm -ivh http://repo.zabbix.com/zabbix/3.0/rhel/7/x86_64/zabbix-release-3.0-1.el7.noarch.rpm 以上安装完毕后,我们现在来正式安装zabbix3.0,使用如下命令: yum -y install zabbix-server-mysql zabbix-web-mysql zabbix-get 通过上图,我们可以很明显的看出目前zabbix server是3.0.2版本的。 以上安装完毕后,我们现在开始进行zabbix的相关配置。 导入zabbix数据库结构,如下: cd /usr/share/doc/zabbix-server-mysql-3.0.2/ zcat create.sql.gz | mysql -uroot -pilanni zabbix 数据库导入完毕后,我们现在来修改zabbix sever的配置文件,如下: vim /etc/zabbix/zabbix_server.conf LogFile=/var/log/zabbix/zabbix_server.log LogFileSize=0 PidFile=/var/run/zabbix/zabbix_server.pid DBHost=localhost DBName=zabbix DBUser=zabbix DBPassword=zabbix SNMPTrapperFile=/var/log/snmptrap/snmptrap.log Timeout=4 AlertScriptsPath=/usr/lib/zabbix/alertscripts ExternalScripts=/usr/lib/zabbix/externalscripts LogSlowQueries=3000 上述配置文件中,我们只需要关注DBHost、DBName、DBUser、 DBPassword几项即可。这几项是配置zabbix server连接mysql数据库的参数。 以上修改完毕后,我们再来修改下zabbix.conf文件。如下: vim /etc/httpd/conf.d/zabbix.conf Alias /zabbix /usr/share/zabbix <Directory "/usr/share/zabbix"> Options FollowSymLinks AllowOverride None Require all granted <IfModule mod_php5.c> php_value max_execution_time 300 php_value memory_limit 128M php_value post_max_size 16M php_value upload_max_filesize 2M php_value max_input_time 300 php_value always_populate_raw_post_data -1 php_value date.timezone Asia/Chongqing </IfModule> </Directory> 其中php_value date.timezone Asia/Chongqing主要是定义php的时区。 以上修改完毕后,我们把把zabbix-server加入开机启动,并启动zabbix-server,如下: systemctl enable zabbix-server systemctl start zabbix-server 最后重启apache,如下: systemctl restart httpd 然后访问http://192.168.1.9/zabbix/setup.php这个地址,如下: 通过上图,我们可以很明显的看出zabbix3.0已经被正确安装。 当然上述的访问地址也是可以自定义的,我们只需要修改zabbix.conf文件中的alias即可,如下: vim /etc/httpd/conf.d/zabbix.conf 修改完毕后,记得重启apache,如下: systemctl restart httpd 此时访问地址已经更改为http://192.168.1.9/ilanni/setup.php,如下: 到此有关centos7上安装zabbix server 3.0的上半部分已经完毕,下半部分见第三章《配置zabbix3.0》。 二、zabbix server3.0在ubuntu 15上安装 在ubuntu 15上安装zabbix server 3.0就简单的多了,我们也是直接使用apt-get方式进行的。注意:zabbix server3.0在 ubuntu 15与ubuntu 14上安装方法是一样的。 首先安装相关的软件,如下: sudo apt-get -y install gettext unzip rar 下载zabbix server3.0仓库文件,并安装如下: wget http://mirrors.aliyun.com/zabbix/zabbix/3.0/ubuntu/pool/main/z/zabbix-release/zabbix-release_3.0-1%2btrusty_all.deb dpkg -i zabbix-release_3.0-1+trusty_all.deb 开始安装zabbix server,使用如下命令: sudo apt-get update sudo apt-get -y install zabbix-server-mysql zabbix-frontend-php zabbix-get 以上是设置mysql数据库root用户的密码。 以上安装完毕后,我们现在来创建zabbix数据库及其用户,如下: mysql -uroot -p'ilanni' -e "create database zabbix default character set utf8 collate utf8_bin;" && mysql -uroot -p'ilanni' -e "grant all on zabbix.* to 'zabbix'@'%' identified by 'zabbix';" 现在来测试刚刚创建的zabbix用户,是否可以连接mysql数据库,如下: mysql -uzabbix -pzabbix show databases; 以上安装及测试完毕后,我们现在开始进行相关的配置。 导入zabbix数据库结构,如下: cd /usr/share/doc/zabbix-server-mysql zcat create.sql.gz | mysql -uroot -p'ilanni' zabbix 数据库导入完毕后,我们现在来修改zabbix sever的配置文件,如下: vim /etc/zabbix/zabbix_server.conf LogFile=/var/log/zabbix/zabbix_server.log LogFileSize=0 PidFile=/var/run/zabbix/zabbix_server.pid DBHost=localhost DBName=zabbix DBUser=zabbix DBPassword=zabbix SNMPTrapperFile=/var/log/snmptrap/snmptrap.log Timeout=4 AlertScriptsPath=/usr/lib/zabbix/alertscripts ExternalScripts=/usr/lib/zabbix/externalscripts LogSlowQueries=3000 上述配置文件中,我们只需要关注DBHost、DBName、DBUser、 DBPassword几项即可。这几项是配置zabbixserver连接mysql数据库的参数。 以上修改完毕后,我们再来修改下zabbix.conf文件。如下: vim /etc/apache2/conf-enabled/zabbix.conf <IfModule mod_alias.c> Alias /zabbix /usr/share/zabbix </IfModule> <Directory "/usr/share/zabbix"> Options FollowSymLinks AllowOverride None Order allow,deny Allow from all <IfModule mod_php5.c> php_value max_execution_time 300 php_value memory_limit 128M php_value post_max_size 16M php_value upload_max_filesize 2M php_value max_input_time 300 php_value always_populate_raw_post_data -1 php_value date.timezone Asia/Chongqing </IfModule> </Directory> 其中php_value date.timezone Asia/Chongqing主要是定义php的时区。这个和centos7下的配置基本一致。 以上修改完毕后,我们把把zabbix-server加入开机启动,并启动zabbix-server,如下: sudo systemctl enable zabbix-server sudo systemctl start zabbix-server 最后重启apache,如下: sudo systemctl restart apache2.service 然后访问http://192.168.1.231/zabbix/setup.php这个地址,如下: 通过上图,我们可以很明显的看出zabbix server 3.0已经被正确安装。 到此有关ubuntu上安装zabbix server 3.0的上半部分已经完毕,下半部分见第三章《配置zabbix3.0》。 三、配置zabbix 在第一、二章节中,我们已经安装zabbix server3.0的上半部分,这个章节我们来继续安装和配置zabbix。 注意:本章节我们不再进行文字解释,全部都是图片。 打开前面的显示的zabbix3.0的网页,点击下一步,如下: 上图中需要填写的是,我们前面创建的zabbix数据库已经用户和密码。 四、安装zabbix agent 前面我们安装了zabbix server3.0,本章节我们介绍安装zabbix agent端。zabbix agent的安装比较简单,我们只需要安装相应的仓库,然后执行安装命令即可。 4.1 安装zabbix agent 在centos os上安装agent,使用如下命令: rpm -ivh http://mirrors.aliyun.com/zabbix/zabbix/3.0/rhel/6/x86_64/zabbix-release-3.0-1.el6.noarch.rpm yum clean all yum -y install zabbix zabbix-agent 在ubuntu os上安装agent,使用如下命令: wget http://mirrors.aliyun.com/zabbix/zabbix/3.0/ubuntu/pool/main/z/zabbix-release/zabbix-release_3.0-1%2btrusty_all.deb dpkg -i zabbix-release_3.0-1+trusty_all.deb sudo apt-get -y install zabbix-agent 4.2 配置zabbix agent zabbix agent的配置很简单,只需要修改zabbix agent配置文件中的Server、ServerActive和Hostname这三项即可。 其中Server、ServerActive是zabbix server服务器的IP地址,Hostname是被监控端的IP地址,如下: vim /etc/zabbix/zabbix_agentd.conf PidFile=/var/run/zabbix/zabbix_agentd.pid LogFile=/var/log/zabbix/zabbix_agentd.log LogFileSize=0 Server=192.168.1.231 ServerActive=192.168.1.231 Hostname=192.168.1.124 Include=/etc/zabbix/zabbix_agentd.d/ 以上配置完毕后,我们在zabbix web端添加该监控机器时,只需要把honst name与该配置文件中的hostname对应即可。如下: 到此zabbix agent就已经安装完毕。 五、zabbix web中文显示与优化 本章节分为两部分,第一部分是配置zabbix web中文显示,第二部分是优化显示的中文。 5.1 zabbix web中文显示 默认情况下zabbix web显示的是英文,实际上zabbix是支持中文的,我们可以通过修改web端源文件来开启中文。 修改/usr/share/zabbix/include/locales.inc.php文件,把zh_CN所在行的false改为true即可,如下: vim /usr/share/zabbix/include/locales.inc.php +55 最后后点击zabbix web监控网页端右上角人头头像,在弹出的选项卡选择中文语言即可。如下: 注意:如果是在ubuntu OS上面配置文件修改完毕后,在zabbix web后台还是会显示,不支持中文的话,说明ubuntu OS没有安装中文语言包。如下: 我们只需要按照以下三步进行操作,即可解决上述问题。 第一步,安装中文包,如下: sudo apt-get -y install language-pack-zh-hant language-pack-zh-hans 第二步,配置相关环境变量: vim /etc/environment 在环境变量文件中增加语言和编码的设置: LANG="zh_CN.UTF-8" LANGUAGE="zh_CN:zh:en_US:en" 第三步,重新设置本地配置: dpkg-reconfigure locales 现在重启下apache和zabbix-server两个服务就可以,如下: sudo systemctl restart apache2.service sudo systemctl restart zabbix-server.service 更换语言后,如果发现图形出现乱码,我们做如下修改即可。 修改/usr/share/zabbix/include/defines.inc.php文件的第45行和第93行,如下: vim /usr/share/zabbix/include/defines.inc.php define('ZBX_GRAPH_FONT_NAME','mysh'); define('ZBX_FONT_NAME', 'mysh'); 然后下载自己喜欢的字体,改名为msyh放到/usr/share/zabbix/fonts目录下即可。 5.2 中文显示优化 以上做完之后,你会发现尽管zabbix web支持中文,但是有些地方翻译的很不到位。如下: 据小道消息,zabbix官方的中文翻译是一位使用繁体中文的华人工程师进行翻译的。 所以在github上有大神对此进行了重新翻译,github连接地址如下:https://github.com/duanzhanling/zabbix-zh_CN 安装方法如下: wget https://github.com/echohn/zabbix-zh_CN/archive/master.zip unzip master.zip rm /usr/share/zabbix/locale/zh_CN/LC_MESSAGES/frontend.mo cp zabbix-zh_CN-master/frontend.mo /usr/share/zabbix/locale/zh_CN/LC_MESSAGES/frontend.mo 现在重启下apache和zabbix_server两个服务就可以,如下: sudo systemctl restart apache2.service sudo systemctl restart zabbix-server.service 通过上图可以看到,最新的翻译比以前好多了。 本文转自 烂泥行天下 51CTO博客,原文链接:http://blog.51cto.com/ilanni/1769445
前几天发表了一篇那关于Server-uFTP与AD集成的博客,收到了很多同学的反馈还不错。今天咱就再来说说Server-U FTP如何与Windows用户组进行集成,其实这个集成很简单的。 首先,我们还是需要先安装Server-U。在此有关Server-U的按照,我就不多介绍了。Server-U安装完毕后,我们来配置Server-U。新建一个域,如下图: 新建域完毕后,我们返回Server-U的主界面。找到“用户”—“ 配置windows身份验证设置”,如下图: 点击进去后,选中“启用windows验证”及“使用Windows用户组”,如下图: 然后点击“配置Windows用户群组”,如下图: 在上面的那个截图中,有几项我们是必须要填写的。“根目录”、“目录访问”、“总是允许登录”。例如: 默认群组属性设置完毕后,我们来设置可以访问FTP的群组。 如上图,点击“Windows群组”下的“添加”按钮。然后输入,我们可以访问FTP的群组。注意这个群组是要和Windows系统中的用户组一一对应。如下图: Ok,以上设置完毕后。我们现在在Windows系统中添加一个新的用户,让其访问FTP试试,看看能否访问。注意此用户必须是属于Users组,否则根本就无法访问FTP。如下图: 用户添加完毕后,我们测试下是否可以正常登录FTP。 通过上图,我们可以看到Windows系统的用户组,已经可以正常访问FTP了。也就是说,Server-UFTP与Windows用户组集成成功了。 当然,如果你想进一步控制目录的访问权限。那么,你可以看看我发表的另一篇博客《烂泥:分享AD与Server-U集成中权限的控制》。 本文转自 烂泥行天下 51CTO博客,原文链接:http://blog.51cto.com/ilanni/1161184
实验环境: OS : CentOS 6.6 corosync: corosync-1.4.7-1.el6.x86_64 pacemaker:pacemaker-1.1.12-4.el6.x86_64 crmsh:crmsh-2.1-1.6.x86_64.rpm pssh: pssh-2.3.1-2.el6.x86_64.rpm node1: hostname: node2.1inux.com IP :172.16.66.81 node2: hostname: node2.1inux.com IP : 172.16.66.82一、前期环境配置 为了配置一台Linux主机成为HA的节点,通常需要做出如下的准备工作: 1)所有节点的主机名称和对应的IP地址解析服务可以正常工作,且每个节点的主机名称需要跟"uname -n“命令的结果保持一致;因此,需要保证两个节点上的/etc/hosts文件均为下面的内容: 1 2 172.16.66.81 node1.1inux.com node1 172.16.66.82 node2.1inux.com node2 为了使得重新启动系统后仍能保持如上的主机名称,还分别需要在各节点执行类似如下的命令: 1 2 3 4 5 6 Node1: # sed -i 's@\(HOSTNAME=\).*@\1node1.1inux.com@g' /etc/sysconfig/network # hostname node1.1inux.com Node2: # sed -i 's@\(HOSTNAME=\).*@\1node2.1inux.com@g' /etc/sysconfig/network # hostname node2.1inux.com 2、设定 node1 、node2基于ssh秘钥的认证的配置 1 2 3 4 5 6 Node1: [root@node1 ~]# ssh-keygen -t rsa -f /root/.ssh/id_rsa -P '' [root@node1 ~]# ssh-copy-id -i /root/.ssh/id_rsa.pub root@172.16.66.82 Node2: [root@node2 ~]# ssh-keygen -t rsa -f /root/.ssh/id_rsa -P '' [root@node2 ~]# ssh-copy-id -i /root/.ssh/id_rsa.pub root@172.16.66.81 3、时间同步配置 1 2 3 4 [root@node1 yum.repos.d]# ntpdate 172.16.0.1 ; ssh node2 'ntpdate 172.16.0.1' 30 May 16:20:20 ntpdate[2351]: adjust time server 172.16.0.1 offset 0.195961 sec 30 May 16:20:21 ntpdate[1994]: step time server 172.16.0.1 offset 1.033553 sec [root@node1 yum.repos.d]# 验证时间同步: 1 2 3 4 [root@node2 ~]# date; ssh node1 "date" Sat May 30 16:51:13 CST 2015 Sat May 30 16:51:13 CST 2015 [root@node2 ~]# 二、安装配置 corosync 、pacemaker 1、安装corosync pacemaker 1 2 3 4 在node1 上面安装: [root@node1 ~]# yum -y install corosync pacemaker 在node2上安装 [root@node2 ~]# yum -y install corosync pacemaker 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 =========================== 查看安装生成的文件 [root@node2 ~]# rpm -ql corosync /etc/corosync /etc/corosync/corosync.conf.example //样例配置文件 /etc/corosync/corosync.conf.example.udpu // /etc/corosync/service.d //服务脚本 /etc/corosync/uidgid.d /etc/dbus-1/system.d/corosync-signals.conf /etc/rc.d/init.d/corosync //服务文件 /etc/rc.d/init.d/corosync-notifyd /etc/sysconfig/corosync-notifyd /usr/bin/corosync-blackbox /usr/libexec/lcrso ... /usr/sbin/corosync /usr/sbin/corosync-cfgtool /usr/sbin/corosync-cpgtool /usr/sbin/corosync-fplay /usr/sbin/corosync-keygen /usr/sbin/corosync-notifyd /usr/sbin/corosync-objctl /usr/sbin/corosync-pload /usr/sbin/corosync-quorumtool .... /var/lib/corosync /var/log/cluster ... =========================== 2、配置corosync ,以下操作在在node2 上操作 1 2 3 [root@node2 ~]# cd /etc/corosync/ [root@node2 corosync]# cp corosync.conf.example corosync.conf [root@node2 corosync]# vim corosync.conf 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 # Please read the corosync.conf.5 manual page compatibility: whitetank totem { version: 2 # secauth: Enable mutual node authentication. If you choose to # enable this ("on"), then do remember to create a shared # secret with "corosync-keygen". secauth: on //开启安全认证 threads: 0 //线程数 0 表示不基于线程模式工作而是进程 # interface: define at least one interface to communicate # over. If you define more than one interface stanza, you must # also set rrp_mode. interface { # Rings must be consecutively numbered, starting at 0. ringnumber: 0 //环数目 一般保持为0 # This is normally the *network* address of the # interface to bind to. This ensures that you can use # identical instances of this configuration file # across all your cluster nodes, without having to # modify this option. bindnetaddr: 172.16.0.0 //网络地址 更改为主机所在网络的网络地址 # However, if you have multiple physical network # interfaces configured for the same subnet, then the # network address alone is not sufficient to identify # the interface Corosync should bind to. In that case, # configure the *host* address of the interface # instead: # bindnetaddr: 192.168.1.1 # When selecting a multicast address, consider RFC # 2365 (which, among other things, specifies that # 239.255.x.x addresses are left to the discretion of # the network administrator). Do not reuse multicast # addresses across multiple Corosync clusters sharing # the same network. mcastaddr: 239.235.88.8 //多播地址 # Corosync uses the port you specify here for UDP # messaging, and also the immediately preceding # port. Thus if you set this to 5405, Corosync sends # messages over UDP ports 5405 and 5404. mcastport: 5405 //多播地址监听端口 # Time-to-live for cluster communication packets. The # number of hops (routers) that this ring will allow # itself to pass. Note that multicast routing must be # specifically enabled on most network routers. ttl: 1 } } logging { # Log the source file and line where messages are being # generated. When in doubt, leave off. Potentially useful for # debugging. fileline: off # Log to standard error. When in doubt, set to no. Useful when # running in the foreground (when invoking "corosync -f") to_stderr: no # Log to a log file. When set to "no", the "logfile" option # must not be set. to_logfile: yes //是否记录日志 logfile: /var/log/cluster/corosync.log //日志文件保存位置 # Log to the system log daemon. When in doubt, set to yes. to_syslog: no //是否记录系统日志 一般只记录一份 设置为NO # Log debug messages (very verbose). When in doubt, leave off. debug: off # Log messages with time stamps. When in doubt, set to on # (unless you are only logging to syslog, where double # timestamps can be annoying). timestamp: on //是否开启时间戳功能 logger_subsys { subsys: AMF debug: off } } //添加如下行 使pacemaker 以corosync插件方式运行 service { ver: 0 name: pacemaker use_mgmtd: yes } aisexec { user: root group: root } ======================================= 生成corosync的密钥文件 查看 # corosync-keygen使用方法: corosync-keygen是从/dev/random中读取随机数,如果此熵池中随机数过少,可能导致无法生成密钥,但可以通过下载软件或其他方案来产生大量I/O从而增加熵池中的随机数,编译生成密钥 1 2 3 4 5 [root@node2 ~]# corosync-keygen ..... Press keys on your keyboard to generate entropy (bits = 896). Press keys on your keyboard to generate entropy (bits = 960). Writing corosync key to /etc/corosync/authkey. //生成的密钥文件保存的位置 3、查看网卡是否开启了组播MULTICAST功能如果没有开启,要手动开启 1 2 3 4 5 6 [root@node2 corosync]# ip link show 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 00:0c:29:3d:a9:a1 brd ff:ff:ff:ff:ff:ff [root@node2 corosync]# 4、将corosync.conf 和authkey复制到node1中 1 2 3 4 [root@node2 corosync]# scp authkey corosync.conf node1:/etc/corosync/ authkey 100% 128 0.1KB/s 00:00 corosync.conf 100% 2773 2.7KB/s 00:00 [root@node2 corosync]# 三、安装crmsh RHEL自6.4起不再提供集群的命令行配置工具crmsh,转而使用pcs;所以如果想使用crmsh可以自行安装: 分别在node1和node2 上安装crmsh和pssh 1 2 3 [root@node2 ~]# ls anaconda-ks.cfg crmsh-2.1-1.6.x86_64.rpm install.log install.log.syslog pssh-2.3.1-2.el6.x86_64.rpm [root@node2 ~]# yum --nogpgcheck localinstall crmsh-2.1-1.6.x86_64.rpm pssh-2.3.1-2.el6.x86_64.rpm 将此两个安装文件复制到node1上进行安装 1 2 [root@node2 ~]# scp crmsh-2.1-1.6.x86_64.rpm pssh-2.3.1-2.el6.x86_64.rpm node1:/root/ [root@node1 ~]# yum --nogpgcheck localinstall crmsh-2.1-1.6.x86_64.rpm pssh-2.3.1-2.el6.x86_64.rpm 查看安装crmsh生成的文件 1 2 3 4 5 6 7 8 9 10 11 ---------------------- [root@node1 ~]# rpm -ql crmsh /etc/bash_completion.d/crm.sh /etc/crm /etc/crm/crm.conf .... /usr/sbin/crm /usr/share/crmsh ... /var/cache/crm --------------------------- 查看pssh生成的文件 1 2 3 4 5 6 7 8 9 10 11 12 [root@node1 ~]# rpm -ql pssh /usr/bin/pnuke /usr/bin/prsync /usr/bin/pscp.pssh /usr/bin/pslurp /usr/bin/pssh ..... ..... /usr/libexec/pssh /usr/libexec/pssh/pssh-askpass ..... [root@node1 ~]# 四、验证: 1、启动 corosync 1 2 3 [root@node1 ~]# service corosync start Starting Corosync Cluster Engine (corosync): [ OK ] [root@node2 ~]# 2、验证端口: 1 2 3 4 [root@node1 log]# ss -tunl | grep :5405 udp UNCONN 0 0 172.16.66.82:5405 *:* udp UNCONN 0 0 239.235.1.8:5405 *:* [root@node2 log]# 3、查看corosync引擎是否正常启动: 1 # grep -e "Corosync Cluster Engine" -e "configuration file" /var/log/cluster/corosync.log 如图 3 4、查看初始化成员节点通知是否正常发出: 如图4 5、检查启动过程中是否有错误产生。下面的错误信息表示packmaker不久之后将不再作为corosync的插件运行,因此,建议使用cman作为集群基础架构服务;此处可安全忽略。 图5 6、查看pacemaker是否正常启动,图6 如果上面命令执行均没有问题,接着可以执行如下命令启动node2上的corosync [root@node1 ~]# ssh node2 -- /etc/init.d/corosync start 注意:启动node2需要在node1上使用如上命令进行,不要在node2节点上直接启动。 使用crmsh命令查看集群节点的启动状态 图7 五、配置集群的工作属性 1、corosync默认启用了stonith,而当前集群并没有相应的stonith设备,因此此默认配置目前尚不可用,这可以通过如下命令验正: 禁用后查看 # crm configure property stonith-enabled=false 图9 2、使用crmsh命令查看当前的配置信息 图10 [root@node1 ~]# crm configure show node node1.1inux.com node node2.1inux.com property cib-bootstrap-options: \ dc-version=1.1.11-97629de \ cluster-infrastructure="classic openais (with plugin)" \ expected-quorum-votes=2 \ stonith-enabled=false //stonith 已被禁用 [root@node1 ~]# 也可以进入crm命令模式关闭 图13 将no-quorum-policy 设置为ignore 1 2 3 4 5 6 7 8 9 10 11 crm(live)configure# property no-quorum-policy=ignore crm(live)configure# show node node1.1inux.com \ attributes standby=off node node2.1inux.com \ attributes standby=off property cib-bootstrap-options: \ dc-version=1.1.11-97629de \ cluster-infrastructure="classic openais (with plugin)" \ expected-quorum-votes=2 \ stonith-enabled=false \ no-quorum-policy=ignore 3、为集群添加集群资源 corosync支持heartbeat,LSB和ocf等类型的资源代理,目前较为常用的类型为LSB和OCF两类,stonith类专为配置stonith设备而用; 可以通过如下命令查看当前集群系统所支持的类型: [root@node1 ~]# crm ra classes 如果想要查看某种类别下的所用资源代理的列表,可以使用类似如下命令实现: # crm ra list lsb # crm ra list ocf heartbeat # crm ra list ocf pacemaker # crm ra list stonith # crm ra info [class:[provider:]]resource_agent 例如: # crm ra info ocf:heartbeat:IPaddr 图12 六、配置高可用的Web集群 1、为web集群创建一个IP地址资源,以在通过集群提供web服务时使用 1 2 3 4 crm(live)configure# primitive webip ocf:heartbeat:IPaddr params ip=172.16.66.100 nic=eth0 cidr_netmask=16 op monitor interval=10 timeout=20s crm(live)configure# verify crm(live)configure# commit crm(live)configure# 然后查看node1 ip 信息如图18 ,看以看到66.100 已经在node1上生效 进入crm 命令行 下线node1 操作 crm(live)node# standby 然后查看node节点状态信息 图15 图15 可以看到node1 已经下线 现在在线的是node2 查看node2 IP 图19 OK IP配置完成,接下来我们配置httpd 2、高可用集群Web的配置 使用yum源分别在node1、node2 安装httpd 分别启动node1、node2上的httpd,并为其创建相应的主页 1 2 3 4 5 6 7 8 node1: [root@node1 ~]# service httpd start Starting httpd: [ OK ] [root@node1 ~]# echo "<h1>node1.1inux.com</h1>" > /var/www/html/index.html [root@node1 ~]# curl 172.16.66.81 <h1>node1.1inux.com</h1> [root@node1 ~]# chkconfig httpd off [root@node1 ~]# service httpd stop 1 2 3 4 5 6 7 8 node2: [root@node2 ~]# service httpd start Starting httpd: [ OK ] [root@node2 ~]# echo "<h1>node2.1inux.com</h1>" > /var/www/html/index.html [root@node2 ~]# curl 172.16.66.82 <h1>node2.1inux.com</h1> [root@node2 ~]# service httpd stop [root@node2 ~]# chkconfig httpd off 然后再node1 上配置如下 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 configure # primitive webserver lsb:httpd op monitor interval=10 timeout=20s crm(live)configure# verify crm(live)configure# commit crm(live)configure# group ip_web webip webserver //创建组 crm(live)configure# verify crm(live)configure# commit crm(live)configure# show node node1.1inux.com \ attributes standby=off node node2.1inux.com \ attributes standby=off primitive webip IPaddr \ params ip=172.16.66.100 nic=eth0 cidr_netmask=16 \ op monitor interval=10 timeout=20s primitive webserver lsb:httpd \ op monitor interval=10 timeout=20s group ip_web webip webserver property cib-bootstrap-options: \ dc-version=1.1.11-97629de \ cluster-infrastructure="classic openais (with plugin)" \ expected-quorum-votes=2 \ stonith-enabled=false \ no-quorum-policy=ignore 1 2 3 4 5 6 7 8 9 10 11 12 13 14 crm(live)configure# cd .. crm(live)# status Last updated: Sun May 31 00:27:05 2015 Last change: Sun May 31 00:24:37 2015 Stack: classic openais (with plugin) Current DC: node2.1inux.com - partition with quorum Version: 1.1.11-97629de 2 Nodes configured, 2 expected votes 2 Resources configured Online: [ node1.1inux.com node2.1inux.com ] Resource Group: ip_web webip (ocf::heartbeat:IPaddr): Started node1.1inux.com webserver (lsb:httpd): Started node1.1inux.com //就可以看到此时 webip webserver 都在node1上面了 crm(live)# 然后我们访问http://172.16.66.100,如图20 ,显示的是node1页面 然后我们在node1上运行如下命令,然后再访问 http://172.16.66.100 [root@node1 ~]# service corosync stop Signaling Corosync Cluster Engine (corosync) to terminate: [ OK ] Waiting for corosync services to unload:. [ OK ] [root@node1 ~]# 此时访问的页面已经变成了node2 OK 基于heartbeat,crmsh的高可用集群已经搭建完毕 本文转自 1inux 51CTO博客,原文链接:http://blog.51cto.com/1inux/1659046
今天我们来学习下有关nginx的负载均衡配置。nginx的负载均衡是通过nginx的upstream模块和proxy_pass反向代理来实现的。 说明:有三台服务器,前端的A服务器使用nginx进行负载均衡配置。后端是两台配置的相同服务器,以访问a.ilanni.com这个域名为例。结构图,如下: A服务器对外(公网)开放80端口,B、C服务器就是两台配置相同的服务器。B服务器开放8080端口,C服务器开放8090端口。当客户端访问a.ilanni.com域名时,A服务器根据nginx的upstream模块相应策略进行分配客户端访问到B服务器还是C服务器。 注意B服务器和C服务器内容是相同的。但是在此,我们为了看到实验效果,我在B、C服务器配置了不同的内容。B服务器的默认页面现实的内容为:The Server is web1_192.168.1.249:8080。C服务器的默认页面现实的内容为:The Server is web2_192.168.1.249:8090。如下: nginx负载均衡的默认是使用轮询方式进行分配的,而且默认的权重为1,并且权重越大被访问的几率越大。 我们先配置A服务器的nginx,如下: cat /usr/local/nginx/conf/nginx.conf|grep -v ^#|grep -v ^$ upstream a.ilanni.com { server 192.168.1.248:8080; server 192.168.1.249:8090; } location / { proxy_pass http://a.ilanni.com; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } 注意上图中,标记出来的第一部分。其中upstream就是做负载均衡使用的。http://a.ilanni.com;就是我们要访问的域名,通过proxy_pass反向代理到upstream下的服务器中。 第二部分就是我们要反向代理的域名,注意在此我们监听的是80端口,而且这个server标签中,我并没有配置server_name。其实配置server_name也是可以的,不过最后的效果是一样的,这个是经过测试的。 第三部分,在此我配置的就是一个虚拟主机。监听的是8080端口,并且在此我也配置了server_name。这个主要是为了做对比使用的。 我们现在先启动A服务器的nginx,并且访问a.ilanni.com:8080。如下: 可以看到目前A服务器的nginx已经可以正常访问了。注意我们在此访问的是http://a.ilanni.com:8080。 现在开始配置B、C服务器的nginx,配置内容如下: B、C服务器的nginx配置完毕后,我们现在来启动各自的nginx服务并访问,如下: 通过上图,我们可以看到B、C服务器的nginx已经正常访问了。那么我现在来访问http://a.ilanni.com看看能不能达到我们所要的效果。如下: 可以看到我们现在访问http://a.ilanni.com已经反向代理到upstream下的B服务器,并且现在显示的是B服务器的内容。 再次刷新页面,显示如下: 刷新页面后,你会发现这次显示的是C服务器的内容。也说明http://a.ilanni.com已经反向代理到C服务器上。 你可以多次刷新页面,会发现显示的内容是B、C服务器交替出现。 为什么会是这样呢? 其实在文章前面,我已经介绍了nginx的upstream负载均衡,在没有其他配置的情况默认使用的策略是轮询方式的,而且默认的权重为1。 也就是说:upstream a.ilanni.com { server 192.168.1.248:8080; server 192.168.1.249:8090; } 中B、C服务器的默认权重都是一样为1。那么在nginx轮询时,所以B、C服务器会交替出现。 如果我们现在把B服务器的权重设置为5,C服务器还是使用默认看看实际情况。配置如下: upstream a.ilanni.com { server 192.168.1.248:8080 weight=5; server 192.168.1.249:8090; } 再次访问http://a.ilanni.com,首先显示的还是B服务器的内容。然后刷新,你会发现大约大约刷新了5次左右,才会显示C服务器的内容。这就权重的作用,服务器的权重数值越高,被分配到客户端的请求次数越多。 注意以上实验,我们是在A、B、C服务器是在同一个局域网,对公网来说只是开放了A服务器的80端口。如果这三台服务器全部是公网IP的话,那就是我们下篇文章要介绍的内容了,有关nginx反向代理的使用。 到此,有关nginx的负载均衡我们基本上介绍完毕后。下面在辅助介绍下,nginx的upstream目前支持以下几种方式的分配: 1)、轮询(默认) 每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除。 2)、weight 指定轮询几率,weight和访问比率成正比,用于后端服务器性能不均的情况。设置服务器的权重,权重数值越高,被分配到客户端的请求次数越多,默认值为1。 3)、ip_hash 每个请求按访问IP的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session的问题。 4)、fair(第三方) 按后端服务器的响应时间来分配请求,响应时间短的优先分配。 5)、url_hash(第三方)按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器,后端服务器为缓存时比较有效。 本文转自 烂泥行天下 51CTO博客,原文链接:http://blog.51cto.com/ilanni/1569654
hi 欢迎阅读此文,此文主要讲解 haproxy 的安装与配置,还有两个shell script : haproxy_install.sh 用于haproxy安装与配置 haproxy.sh 用于管理haproxy 服务,功能 开启 关闭 重启 此文没有介绍haproxy ,因为既然您来到这里,说明您很关心haproxy 可能早就闻其大名了(4,7层负载均衡软件),haproxy 优点与强大的功能我就不重复了,好了下面开始! 1 haproxy 配置文档,#号为注释,用于功能说明 update 20120904 $ cat /usr/local/haproxy/haproxy.cfg #HAProxy配置中分成五部分内容,当然这些组件不是必选的,可以根据需要选择部分作为配置。 #global:参数是进程级的,通常和操作系统(OS)相关。这些参数一般只设置一次,如果配置无误,就不需要再次配置进行修改 #defaults:配置默认参数的,这些参数可以被利用配置到frontend,backend,listen组件 #frontend:接收请求的前端虚拟节点,Frontend可以根据规则直接指定具体使用后端的backend(可动态选择)。 #backend:后端服务集群的配置,是真实的服务器,一个Backend对应一个或者多个实体服务器。 #listen:Frontend和Backend的组合体。 global log 127.0.0.1 local1 maxconn 65000 #最大连接数 chroot /usr/local/haproxy #安装目录 uid 99 #用户haproxy gid 99 #组haproxy daemon #守护进程运行 nbproc 2 #进程数量 pidfile /usr/local/haproxy/logs/haproxy.pid #haproxy pid defaults log global mode http #7层#默认的模式mode {tcp|http|health},tcp是4层,http是7层,health只会返回OK option httplog #http 日志格式 option httpclose #主动关闭http通道,HA-Proxy不支持keep-alive模式 option redispatch #serverId对应的服务器挂掉后,强制定向到其他健康的服务器 option forwardfor #后端服务器需要获得客户端的真实IP,将从Http Header中获得客户端IP option dontlognull #来防止记录 Alteo(4层负载均衡)发出的健康检测,如果一个 session 交互没有数据,这个 session就不会被记录 maxconn 50000 #最大连接数 contimeout 5000 #连接超时(毫秒) clitimeout 50000 #客户端超时(毫秒) srvtimeout 50000 #服务器超时(毫秒) #errorfile 502 /usr/local/haproxy/html/maintain.html #errorfile 503 /usr/local/haproxy/html/maintain.html #errorfile 504 /usr/local/haproxy/html/maintain.html frontend test.com #定义前端服务器(haproxy) bind *:80 #监听地址 # acl static path_end -i .jpg .png .bmg .gif .css .js #acl web-client path_beg -i /vsphere-client acl bbs hdr_reg(host) -i ^(bbs.test.com|shequ.test.com|forum|phpwind|home) acl blog hdr_reg(host) -i ^(blog.test.com|t) #acl jsp path_end -i .jsp .do acl monitor hdr_beg(host) -i monitor.test.com #定义ACL名称,对应的请求的主机头是monitor.test.com acl www hdr_beg(host) -i www.test.com acl jsp hdr_reg(host) -i ^(center.test.com|java|jsp) # use_backend tomcat.test.com if jsp use_backend cache.test.com if static use_backend monitor.test.com if monitor use_backend bbs.test.com if bbs use_backend blog.test.com if blog use_backend www.test.com if www #use_backend vsphere-client if web-client # default_backend www.test.com #指定默认的后端服务器 backend monitor.test.com #定义后端服务器群(web server/apache/nginx/iis..) mode http option forwardfor #后端服务器(apache/nginx/iis/*),从Http Header中获得客户端IP balance leastconn #负载均衡的方式,最小连接 cookie SERVERID #插入serverid到cookie中,serverid后面可以定义 option httpchk HEAD /check.html #用来做健康检查html文档 #option httpchk HEAD /index.php HTTP/1.1\r\nHost:monitor.test.com #HTTP && Host server monitor 10.0.100.70:80 cookie monitor check inter 2000 rise 3 fall 3 weight 3 #服务器定义: #cookie server1表示serverid为server1; #check inter 2000 是检测心跳频率(check 默认 ); #rise 3 表示 3次正确认为服务器可用; #fall 3 表示 3次失败认为服务器不可用; #weight 表示权重。 backend bbs.test.com mode http option forwardfor balance roundrobin #负载均衡的方式,轮询方式 cookie SERVERID insert indirect #插入serverid到cookie中,serverid后面可以定义 option httpchk HEAD /check.html #option httpchk HEAD /index.php HTTP/1.1\r\nHost:monitor.test.com #HTTP && Host server bbs01 10.0.100.75:80 cookie bbs01 check inter 2000 rise 3 fall 3 weight 3 backend blog.test.com mode http option forwardfor balance roundrobin cookie SERVERID option httpchk HEAD /check.html server blog01 10.0.100.76:80 cookie blog01 check inter 2000 rise 3 fall 3 weight 3 backend www.test.com mode http option forwardfor balance roundrobin #负载均衡的方式,轮询方式 cookie SERVERID option httpchk HEAD /check.html server www01 10.0.100.71:80 cookie www01 check inter 2000 rise 3 fall 3 weight 3 backend cache.test.com mode http option forwardfor #balance uri len 15 #url hash balance roundrobin cookie SERVERID server squid01 10.0.100.72:80 cookie squid01 check inter 2000 rise 3 fall 3 weight 3 server squid02 10.0.100.73:80 cookie squid02 check inter 2000 rise 3 fall 3 weight 3 backend tomcat.test.com mode http option forwardfor balance roundrobin cookie SERVERID option httpchk HEAD /index.html server tomcat01 10.0.100.77:8080 cookie tomcat01 check inter 2000 rise 3 fall 3 weight 3 server tomcat02 10.0.100.78:8080 cookie tomcat02 check inter 2000 rise 3 fall 3 weight 3 #backend vsphere-client # mode http # option forwardfor header ORIG_CLIENT_IP # balance roundrobin # server server1 10.0.100.81:80 redir https://192.168.57.81:443 check inter 2000 rise 3 fall 3 weight 3 listen admin_stat #status bind 0.0.0.0:8080 #监听端口 mode http #http的7层模式 stats refresh 30s #统计页面自动刷新时间 stats uri /haproxy_stats_url #统计页面URL stats realm Haproxy\ Statistics #统计页面密码框上提示文本 stats auth admin:admin #统计页面用户名和密码设置 stats hide-version #隐藏统计页面上HAProxy的版本信息 stats admin if TRUE #手工启用/禁用,后端服务器 2 haproxy 安装脚本 这里 3 haproxy 服务脚本 这里 4 运行 haproxy ./haproxy.sh usage: ./haproxy.sh {start|stop|restart} ./haprroxy.sh start 5 haproxy 监控页面 http://yourip:8080/haproxy_stats_url 用户名与密码:admin 结束 shell 脚本如有bug ,欢迎反馈! mail:dngood@sina.com qq群: 37275208 #update 20120701 TProxy透明代理相关配置 http://yupengyan.com/quick-installation-of-haproxy-on-centos6-2.html Configure HAProxy with TPROXY kernel for full transparent proxy http://blog.loadbalancer.org/configure-haproxy-with-tproxy-kernel-for-full-transparent-proxy/ haproxy-doc http://code.google.com/p/haproxy-docs/w/list 本文转自 dongnan 51CTO博客,原文链接:http://blog.51cto.com/dngood/738634
慢查询日志用来优化Query语句,以下是有关的几个参数,5.5版本以后可以到微秒(μs)新版本中还有long_query_io(读取次数) log_queries_not_using_indexes(没有使用索引的SQL) log_throttle_not_using_indexes(控制每分钟不实用索引SQL记录的次数) mysql> show variables like '%slow%'; | slow_query_log | ON #最好在配置文件不要开启 用的时候再打开开关 | slow_query_log_file | /opt/mysql/data/hack-slow.log | #指定慢查询日志文件 +---------------------------+-------------------------------+ mysql> show variables like '%long%'; | long_query_time | 0.050000 | #这里看到时间为秒 mysql> 通过tail(没有规律)或者mysqldumslow查看慢查询日志(常用) [root@hack data]# mysqldumpslow --help 常用的解释一下 Usage: mysqldumpslow [ OPTS... ] [ LOGS... ] -s ORDER (可以根据查询时间、行数、锁定时间,总数及他们的平均值) what to sort by (al, at, ar, c, l, r, t), 'at' is default al: average lock time ar: average rows sent at: average query time c: count l: lock time r: rows sent t: query time -r (倒序) reverse the sort order (largest last instead of first) -t NUM (指定返回的条数) just show the top n queries -g PATTERN(用来过滤) grep: only consider stmts that include this string eg:查询最慢执行时间最慢的10条???????? 针对mysqldumpslow的输出做个说明 [root@hack data]# mysqldumpslow hack-slow.log 这个是我的输出 Reading mysql slow query log from hack-slow.logCount: 5 Time=0.01s (0s) Lock=0.00s (0s) Rows=128.8 (644), root[root]@localhost select * from ssq where s2 =N limit N [root@hack data]# 下面进行说明: Count 是我执行了五次这样的query, select * from ssq where s2 =2 limit 123 select * from ssq where s2 =4 limit 123 认为是这种类型:select * from ssq where s2 =N limit N所以认为是一样的 Time 执行这类query的时候的平均时间(0)s Lock Rows 同样如此 [root@hack data]# mysqldumpslow -s r -t 10 hack-slow.log #我是按返回的行数进行的排序可以看到是用的Rows括号的值,如果用外面的就用参数ar Reading mysql slow query log from hack-slow.log Count: 1 Time=25.94s (25s) Lock=0.00s (0s) Rows=47823.0 (47823), root[root]@localhost select * from t Count: 1 Time=0.03s (0s) Lock=0.00s (0s) Rows=1225.0 (1225), root[root]@localhost select * from dlt Count: 5 Time=0.01s (0s) Lock=0.00s (0s) Rows=128.8 (644), root[root]@localhost select * from ssq where s2 =N limit N Count: 1 Time=0.00s (0s) Lock=0.00s (0s) Rows=234.0 (234), root[root]@localhost select * from dlt limit N Count: 1 Time=0.01s (0s) Lock=0.00s (0s) Rows=146.0 (146), root[root]@localhost [root@hack data]# mysqldumpslow -s at -t 10 hack-slow.log #用at排序 Reading mysql slow query log from hack-slow.log Count: 1 Time=25.94s (25s) Lock=0.00s (0s) Rows=47823.0 (47823), root[root]@localhost select * from t Count: 1 Time=0.03s (0s) Lock=0.00s (0s) Rows=1225.0 (1225), root[root]@localhost select * from dlt Count: 5 Time=0.01s (0s) Lock=0.00s (0s) Rows=128.8 (644), root[root]@localhost select * from ssq where s2 =N limit N [root@hack data]# tail -f hack-slow.log Tcp port: 3306 Unix socket: /usr/local/mysql/mysql.sock Time Id Command Argument /usr/local/mysql/bin/mysqld, Version: 5.6.14-log (Source distribution). started with: Tcp port: 3306 Unix socket: /usr/local/mysql/mysql.sock Time Id Command Argument # Time: 150417 1:23:49 # User@Host: root[root] @ localhost [] Id: 1 # Query_time: 0.118892 Lock_time: 0.000000 Rows_sent: 1 Rows_examined: 0 SET timestamp=1429205029; select version(); # Time: 150417 1:24:20 # User@Host: root[root] @ localhost [] Id: 1 # Query_time: 0.426234 Lock_time: 0.139966 Rows_sent: 5 Rows_examined: 5 SET timestamp=1429205060; show variables like '%slow%'; ^C 另外从5.1版本之后,开始慢查询日志可以记录到数据库中,在mysql中存在一个slow_log的表 mysql> show create table mysql.slow_log \G *************************** 1. row *************************** Table: slow_log Create Table: CREATE TABLE `slow_log` ( `start_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, `user_host` mediumtext NOT NULL, `query_time` time NOT NULL, `lock_time` time NOT NULL, `rows_sent` int(11) NOT NULL, `rows_examined` int(11) NOT NULL, `db` varchar(512) NOT NULL, `last_insert_id` int(11) NOT NULL, `insert_id` int(11) NOT NULL, `server_id` int(10) unsigned NOT NULL, `sql_text` mediumtext NOT NULL, `thread_id` bigint(21) unsigned NOT NULL ) ENGINE=CSV DEFAULT CHARSET=utf8 COMMENT='Slow log' 1 row in set (0.07 sec) mysql> 可以看到该表的引擎为CSV mysql> show variables like '%log_output%'; +---------------+-------+ | Variable_name | Value | +---------------+-------+ | log_output | FILE | +---------------+-------+ 1 row in set (0.03 sec) mysql> set global log_output='FILE,TABLE';更改日志输出到文件和表中 Query OK, 0 rows affected (0.07 sec) mysql> show variables like '%log_output%'; +---------------+------------+ | Variable_name | Value | +---------------+------------+ | log_output | FILE,TABLE | +---------------+------------+ 1 row in set (0.09 sec) mysql> select sleep(10); +-----------+ | sleep(10) | +-----------+ | 0 | +-----------+ 1 row in set (10.09 sec) mysql> select * from mysql.slow_log \G 我从打开table到查询有两条语句达到慢查询设定的时间 *************************** 1. row *************************** start_time: 2015-04-17 01:33:50 user_host: root[root] @ localhost [] query_time: 00:00:00 lock_time: 00:00:00 rows_sent: 0 rows_examined: 0 db: last_insert_id: 0 insert_id: 0 server_id: 13 sql_text: set global log_output='FILE,TABLE' thread_id: 1 *************************** 2. row *************************** start_time: 2015-04-17 01:34:17 user_host: root[root] @ localhost [] query_time: 00:00:10 lock_time: 00:00:00 rows_sent: 1 rows_examined: 0 db: last_insert_id: 0 insert_id: 0 server_id: 13 sql_text: select sleep(10) thread_id: 1 2 rows in set (0.01 sec) mysql> 修改slow_log的存储引擎为myisam mysql> alter table mysql.slow_log engine=myisam; ERROR 1580 (HY000): You cannot 'ALTER' a log table if logging is enabled mysql> set global slow_query_log=off; Query OK, 0 rows affected (0.00 sec) mysql> alter table mysql.slow_log engine=myisam; Query OK, 3 rows affected (0.15 sec) Records: 3 Duplicates: 0 Warnings: 0 mysql> 本文转自 aklaus 51CTO博客,原文链接:http://blog.51cto.com/aklaus/1633633
模块使用 模块是Python组织代码的基本方式。 一个Python脚本可以单独运行,也可以导入到另一个脚本中运行,当脚本被导入运行时,我们将其称为模块(module)。 所有的.py文件都可以作为一个模块导入 模块名与脚本的文件名相同 例如我们编写了一个名为hello.py的脚本,则可以在另一个脚本中用import hello语句来导入它。 实例: [root@centos7-3 python]# cat add.py #!/usr/bin/python def addNum(x,y): return x + y print addNum(10,10) [root@centos7-3 python]# cat fun.py #!/usr/bin/python import add print add.addNum(5,4) 执行: [root@centos7-3 python]# python fun.py 20 9 执行fun.py后的结果将add.py里的结果(20)打印出来了,现在只想要fun.py执行的结果,操作如下: 添加判断:如果是主函数则执行,add.py就是主函数 结果: 包 Python的模块可以按目录组织为包 创建一个包的步骤: - 创建一个名字为包名的目录 - 在该目录下创建一个__init__.py文件 - 根据需要,在该目录下存放脚本文件或已编译的扩展及子包 - import pack.m1, pack.m2, pack.m3 实例: 1、创建init.py [root@centos7-3 python]# pwd /root/python [root@centos7-3 python]# touch init.py 计算字符数、单词数、行数 [root@centos7-3 fun]# cat word.py #!/usr/bin/python def wordCount(s): chars=len(s) #计算字符数 words=len(s.split()) #计算单词数 lines=s.count('\n') #计算行数 print chars,words,lines if name == 'main': s=open('/etc/passwd').read() wordCount(s) [root@centos7-3 fun]# python word.py 1188 47 24 传入fun的包 In [3]: from fun import word In [4]: ls fun/ fun.sh init.py init.pyc word.py word.pyc In [5]: word.wordCount('asdaaaaaaaaaaaaaa') 面向对象介绍 1、面向过程和面向对象编程 面向过程编程:函数式编程,C程序等 面向对象编程:C++,Java,Python等,若是碰到大的项目,用类表示,对象就是类的实例,类里有很多的方法(函数),如果需要调用,就必须将类实例化 2、类和对象:是面向对象中的两个重要概念 类:是对事物的抽象,比如:人类、球类 对象:是类的一个实例,比如:足球、篮球 实例说明: 球类可以对球的特征和行为进行抽象,然后可以实例化一个真实的球实体出来。 面向对象的主要思想是: 封装 继承 多态 这种思想方便解决较为复杂的项目,且维护起来较为容易。 3、类定义: 类把需要的变量和函数组合成一起,这种包含称为“封装” class A(object): 类的结构: class 类名: 成员变量 – 属性 成员函数 – 方法 实例: class People(object): #定义一个类 coler='yellow' def fun(self): #定义类的方法(函数) self.coler='black' #定义一个变量(属性) print 'I am a %s' %(self.coler) pe=People() #对类实例化,才能调用类 print pe.coler #打印出类的属性 pe.fun() #打印出类的方法 结果: yellow I am a black 本文转自 jiekegz 51CTO博客,原文链接:http://blog.51cto.com/jacksoner/2059219
rsync -a --delete --exclude=webpub_old --exclude=webpub_20100408 /home1/www/ /wwwroot/www rsync -a --delete /home1/down/ /wwwroot/down rsync -a --delete /home1/bbs /wwwroot/bbs rsync -a --delete /home1/db /wwwroot/bbs rsync -a --delete /home1/act /wwwroot/act rsync -a --delete --exclude=web_app_new20100408 /home1/market /wwwroot/market rsync -a --delete /home1/gg /wwwroot/gg rsync -a --delete /home1/phpwind /wwwroot/phpwind rsync -a --delete /home1/spec /wwwroot/spec rsync -a --delete /home1/wiki /wwwroot/wiki rsync -a --delete --exclude=webpub_old --exclude=webpub_20100408 /home1/www/ /wwwroot/www(排除了webpub_old和webpub_20100408两个目录) 本文转自 liang3391 51CTO博客,原文链接:http://blog.51cto.com/liang3391/456612
16、定义用户(User Configurations) 下面方框中内容摘自http://wenku.baidu.com/view/48de918f6529647d272852df.html 1、右击User Configuration,选择Add new user configuration; 2、添加使用单点登录的用户,可以根据实际情况调价,这里默认选择Domain Users; 3、这里一般选择Xenapp Platinum,如果有license的话也可以选择其他; 4、点击Add,进入下一步; 5、选择需要单点登录的应用程序; 6、输入相应的license Server名称; 7、点击Finish完成设置。 17、配置Logon Manager, 登录Web Interface或在线挂件,并启动XenApp已经发布的K3应用,配置登录用户名密码: 如果偶尔一些异常导致无法自动登录,可以在服务器上打开Logon Manager,删除当前登录程序,点击File→New logon,重新配置K/3登录用户名密码及相关设置即可。 18、实现后效果: 可以看到已经自动选择组织机构、帐套并输入了用户名密码后登录: 本文转自 sfih 51CTO博客,原文链接:http://blog.51cto.com/dayday/1154629
http://blog.csdn.net/gui694278452/article/details/7652450 一.NBD简介 NBD(Network Block Device)让你可以将一个远程主机的磁盘空间,当作一个块设备来使用.就像一块硬盘一样.使用它,你可以很方便的将另一台服务器的硬盘空间,增加到本地服务器上. NBD与NFS有所不同.NFS只是提供一个挂载点供客户端使用,客户端无法改变这个挂载点的分区格式. 而NBD提供的是一个块设备,客户端可以把这个块设备格式化成各种类型的分区.更便于用户的使用. NBD是一个内核模块,大部分Linux发行版都已包含它. 二.NBD安装方法在Turbolinux的10以上的版本中,NBD已被编译成模块.保存在/lib/modules/$version/kernel/driver/block/下. 你还需要在服务器端和客户端上安装nbd-server和nbd-client工具. 你可以从官方网站上下载源码包,并分别在服务器端和客户端服务器上进行安装: http://sourceforge.net/projects/nbd我们这里下载nbd-2.8.8.tar.bz2 下载后,执行下列步骤进行安装: # tar jxf nbd-2.8.8.tar.bz2# cd nbd-2.8.8# ./configure# make # make install 或者使用命令行安装: sudo apt-get install nbd-client sudo apt-get install nbd-server 三.NBD使用方法1.示例1: 服务器端提供单个映像文件到客户端a.服务器端配置方法(IP为192.168.1.1)你需要先建立一个磁盘映像文件,作为提供给客户端使用的块设备.我们制作一个300MB的文件当做块设备.# cd /var/tmp# dd if=/dev/zero of=nbd-disk0 bs=104857600 count=3 启动nbd-server,监听1234端口,使用nbd-disk0映像文件.# nbd-server 1234 /var/tmp/nbd-disk0查看nbd进程.# ps -ef | grep nbdroot 11292 1 0 15:02 ? 00:00:00 nbd-server 1234 /var/tmp/nbd-disk0nbd-server用法:nbd-server port file [size][kKmM] [-l authorize_file] [-r] [-m] [-c] [-a timeout_sec]port nbd-server监听端口.file 绑定的映像文件.size 在客户端所见的块设备大小(单位可以是: k,K,m,M).-r|--read-only 只读模式,客户端无法在块设备上进行写操作.-m|--multi-file 多个文件,可以将多个映像文件作为一个块设备提供给客户端.-c|--copy-on-write 所有客户端的写操作被会另存为一个文件,连接断开后,这个文件会被删除. 可以保证映像文件内容不会被修改.-l|--authorize-file file 一个允许访问此nbd的主机列表文件.-a|--idle-time 服务器断开与客户端连接前的最大空闲时间.b.客户端配置方法(IP为192.168.1.2)加载nbd模块.# modprobe nbd# lsmod | grep nbdnbd 26400 0查看nbd设备是否建立.# ls /dev/nbd* -hlbrw-r----- 1 root disk 43, 0 Jul 27 06:40 /dev/nbd0brw-r----- 1 root disk 43, 1 Jul 27 06:40 /dev/nbd1brw-r----- 1 root disk 43, 2 Jul 27 06:40 /dev/nbd2brw-r----- 1 root disk 43, 3 Jul 27 06:40 /dev/nbd3brw-r----- 1 root disk 43, 4 Jul 27 06:40 /dev/nbd4brw-r----- 1 root disk 43, 5 Jul 27 06:40 /dev/nbd5brw-r----- 1 root disk 43, 6 Jul 27 06:40 /dev/nbd6brw-r----- 1 root disk 43, 7 Jul 27 06:40 /dev/nbd7brw-r----- 1 root disk 43, 8 Jul 27 06:40 /dev/nbd8brw-r----- 1 root disk 43, 9 Jul 27 06:40 /dev/nbd9将/dev/nbd0设备与主机连接.# nbd-client 192.168.1.1 1234 /dev/nbd0 Negotiation: ..size = 307200KBbs=1024, sz=307200nbd-client用法:nbd-client [bs=blocksize] host port nbd_device [-swap]bs 用于设置块大小,默认是1024,可以是512,1024.2048,4096host 服务器的主机名或IPport 服务器的监听端口nbd_device 映射到本地的哪个nbd设备(如: /dev/nbd0)-swap 指定nbd设备将用做swap空间nbd-client -d nbd_device 用于断开连接连接成功后,可以查看到nbd-client进程.# ps -ef | grep nbdroot 3156 1 0 06:44 pts/0 00:00:00 nbd-client 192.168.1.1 1234 /dev/nbd0使用前,需要格式化这个块设备.# mkfs.ext3 /dev/nbd0 mke2fs 1.39 (29-May-2006)Filesystem label=OS type: LinuxBlock size=1024 (log=0)Fragment size=1024 (log=0)76912 inodes, 307200 blocks15360 blocks (5.00%) reserved for the super userFirst data block=1Maximum filesystem blocks=6763315238 block groups8192 blocks per group, 8192 fragments per group2024 inodes per groupSuperblock backups stored on blocks: 8193, 24577, 40961, 57345, 73729, 204801, 221185Writing inode tables: done Creating journal (8192 blocks): doneWriting superblocks and filesystem accounting information: doneThis filesystem will be automatically checked every 39 mounts or180 days, whichever comes first. Use tune2fs -c or -i to override.挂载这个块设备.# mkdir /mnt/nbd0# mount /dev/nbd0 /mnt/nbd0 # cd /mnt/nbd0# lslost+found复制/root目录到这个目录中.# cp /root . -rf # lslost+found root断开这个块设备.# umount /mnt/nbd0/# nbd-client -d /dev/nbd0 Disconnecting: que, disconnect, sock, doneKernel call returned: Broken pipeClosing: que, sock, done2.示例2: 服务器端提供多个映像文件到客户端a.服务器端配置# cd /var/tmp# dd if=/dev/zero of=nbd-disk1 bs=104857600 count=3 记录了 3+0 的读入记录了 3+0 的写出314572800 字节 (315 MB) 已复制,0.584027 秒,539 MB/秒# dd if=/dev/zero of=nbd-disk2 bs=104857600 count=3 记录了 3+0 的读入记录了 3+0 的写出314572800 字节 (315 MB) 已复制,1.5128 秒,208 MB/秒# nbd-server 1234 /var/tmp/nbd-disk1 # nbd-server 1235 /var/tmp/nbd-disk1 # nbd-server 1236 /var/tmp/nbd-disk2# ps -ef | grep nbdroot 11292 1 0 15:02 ? 00:00:00 nbd-server 1234 /var/tmp/nbd-disk0root 11599 1 0 15:14 ? 00:00:00 nbd-server 1235 /var/tmp/nbd-disk1root 11606 1 0 15:14 ? 00:00:00 nbd-server 1236 /var/tmp/nbd-disk2b.客户端配置# lsmod | grep nbdnbd 24736 0 # ls /dev/nbd*/dev/nbd0 /dev/nbd11 /dev/nbd14 /dev/nbd3 /dev/nbd6 /dev/nbd9/dev/nbd1 /dev/nbd12 /dev/nbd15 /dev/nbd4 /dev/nbd7/dev/nbd10 /dev/nbd13 /dev/nbd2 /dev/nbd5 /dev/nbd8# nbd-client 192.168.1.1 1234 /dev/nbd0Negotiation: ..size = 307200KBbs=1024, sz=307200# nbd-client 192.168.1.1 1235 /dev/nbd1Negotiation: ..size = 307200KBbs=1024, sz=307200# nbd-client 192.168.1.1 1236 /dev/nbd2Negotiation: ..size = 307200KBbs=1024, sz=307200将nbd1格式化为vfat格式.# mkfs.vfat /dev/nbd1 mkfs.vfat 2.11 (12 Mar 2005)unable to get drive geometry, using default 255/63将nbd2格式化为ext2格式.# mkfs.ext2 /dev/nbd2 mke2fs 1.39 (29-May-2006)Filesystem label=OS type: LinuxBlock size=1024 (log=0)Fragment size=1024 (log=0)76912 inodes, 307200 blocks15360 blocks (5.00%) reserved for the super userFirst data block=1Maximum filesystem blocks=6763315238 block groups8192 blocks per group, 8192 fragments per group2024 inodes per groupSuperblock backups stored on blocks: 8193, 24577, 40961, 57345, 73729, 204801, 221185Writing inode tables: done Writing superblocks and filesystem accounting information: doneThis filesystem will be automatically checked every 21 mounts or180 days, whichever comes first. Use tune2fs -c or -i to override.挂载这3个块设备# cd /mnt# mkdir nbd1 nbd2# mount /dev/nbd0 nbd0# mount /dev/nbd1 nbd1# mount /dev/nbd2 nbd2# df -h Filesystem Size Used Avail Use% Mounted on/dev/nbd0 291M 11M 265M 4% /mnt/nbd0/dev/nbd1 300M 0 300M 0% /mnt/nbd1/dev/nbd2 291M 2.1M 274M 1% /mnt/nbd2# mount/dev/nbd0 on /mnt/nbd0 type ext3 (rw)/dev/nbd1 on /mnt/nbd1 type vfat (rw)/dev/nbd2 on /mnt/nbd2 type ext2 (rw) 本文转自 Tenderrain 51CTO博客,原文链接:http://blog.51cto.com/tenderrain/1983573
这几天抽了个时间,终于把自己阿里云ecs的os升级到了centos7,所以也打算把博客wordpress也升级下,同时还要使用现在比较火的docker技术。 下面把相关wordpress迁移到docker中的相关步骤记录下。 PS:强烈建议OS使用3.0以上内核。 一、备份wordpress数据 在正式迁移wordpress之前,我们需要备份wordpress的相关数据,包括数据库、图片以及主题。 有关wordpress数据库的备份,就是个仁者见仁智者见智的事情了,你通过什么方法都可以备份的。我这边的做法是在本地的一个环境上,使用navicat这个mysql数据库管理工具,把数据传输到本地的环境上。 wordpress图片和主题都在wp-content这个目录下,我们只需要备份这个目录即可。 二、安装docker及其相关软件 wordpress相关数据备份完毕后,我们现在开始安装docker及其相关软件。 2.1 安装docker docker的安装我们可以分为使用脚本快速安装和配置yum源安装,下面分别介绍下。 2.1.1 脚本快速安装 docker的安装比较简单,我们可以直接使用官方提供的脚本快速安装命令进行安装,如下: curl -fsSL https://get.docker.com/ | sh 当然我们也可以使用国内提供的脚本快速安装命令,如下: curl -sSL https://get.daocloud.io/docker | sh 2.1.2 配置yum源安装 通过配置yum源方式安装docker就比较简单,只需要在本地配置yum仓库配置即可。在此我们使用的中科大的docker仓库,配置如下: vim /etc/yum.repos.d/docker.repo [dockerrepo] name=Docker Repository baseurl=https://yum.dockerproject.org/repo/main/centos/7 enabled=1 gpgcheck=1 gpgkey=https://yum.dockerproject.org/gpg yum仓库配置完毕后,我们现在开始安装docker,如下: yum -y install docker-engine 2.1.3 普通用户添加docker权限 如果我们想让普通用户也具有使用docker权限,只需要把该用户添加到docker用户组即可。现在以ilanni这个用户为例,如下: cat /etc/group |grep docker sudo usermod -aG docker ilanni su – ilanni docker ps 2.1.4 docker开机启动 默认情况下docker是没有开机启动的,使用下面命令使docker开机启动,如下: systemctl start docker && systemctl enable docker 2.2 安装docker-compose 因为wordpress需要使用多个docker镜像,所以在此我们使用docker-compose编排工具,进行管理。 安装docker-compose,使用如下命令: curl -L https://github.com/docker/compose/releases/download/1.13.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose chmod +x /usr/local/bin/docker-compose docker-compose –version 2.3 安装iptables centos7默认情况使用的是firewalld作为防火墙,但是对firewalld很是不熟悉,所以还是打算使用iptables。 下面安装iptables,使用如下命令: yum -y install iptables-services iptables 把iptables加入到系统服务,使用如下命令: cp /usr/libexec/iptables/iptables.init /etc/init.d/iptables /etc/init.d/iptables start /etc/init.d/iptables status 把iptables设置为开机启动,使用如下命令: systemctl enable iptables systemctl list-unit-files | grep iptables 关闭firewalld服务,使用如下命令: systemctl disable firewalld.service systemctl status firewalld.service PS:docker及其相关软件安装完毕后,强烈建议重启服务器。 三、下载镜像 在本次wordpress迁移到docker中,我们需要两个镜像mysql镜像和wordpress镜像。其中wordpress镜像中包含apache、php和wordpress,而mysql镜像提供数据库服务。 PS:无论是wordress镜像还是mysql镜像都提供了多个版本,比如:wordpress镜像中有的只提供wordpress功能,没有提供php功能等等。 但是这次为了迁移的方便,我们只使用wordpress提供的全部功能。 除此之外,考虑到众所周知的原因,我们使用国内网易的蜂巢docker。 3.1 下载mysql5.5镜像 因为我现在wordpress的数据库使用的mysql5.5版本,所以我们也要下载mysql5.5的docker镜像,使用如下命令: docker pull hub.c.163.com/library/mysql:5.5 如果要使用官方提供的mysql5.5镜像,使用如下命令: docker pull mysql:5.5 3.2 下载wordpress镜像 wordpress镜像我们使用最新的版本即可,下载最新版本的镜像命令如下: docker pull hub.c.163.com/library/wordpress 如果要使用官方提供的wordpress镜像,使用如下命令: docker pull wordpress 对于wordpress提供的多个版本,我们使用的是包含有apache、php、php-fpm的latest版本。 对于只提供wordpress功能的版本,我们会在以后的文章进行相关讲解。 四、编写docker-compose.yml文件 为了管理容器的方便在此我们使用的是docker-compose来进行的,当然你也可以对每个docker镜像单独来运行。 但是在这为了迁移的方便,我们在这直接使用docker-compose来进行管理。 对于docker-compose,我们只需要编写docker-compose.yml文件,即可。示例如下: vim docker-compose.yml version: '2' services: mysqldb: image: hub.c.163.com/library/mysql:5.5 container_name: ilanni_mysql ports: - "33033:3306" volumes: - ./data:/var/lib/mysql restart: always environment: MYSQL_ROOT_PASSWORD: 123456 MYSQL_DATABASE: ilanni MYSQL_USER: wwwilanni MYSQL_PASSWORD: ilanni123 wordpress: depends_on: - mysqldb image: hub.c.163.com/library/wordpress container_name: ilanni_wordpress ports: - "80:80" restart: always environment: WORDPRESS_DB_HOST: ilanni_mysql:3306 WORDPRESS_DB_NAME: ilanni WORDPRESS_DB_USER: wwwilanni WORDPRESS_DB_PASSWORD: ilanni123 volumes: - ./wp-content/themes/xiu_ilanni:/var/www/html/wp-content/themes/xiu_ilanni - ./wp-content/plugins:/var/www/html/wp-content/plugins - ./wp-content/uploads:/var/www/html/wp-content/uploads - ./favicon.ico:/var/www/html/favicon.ico - ./alivv.txt:/var/www/html/alivv.txt 上述的docker-compose.yml文件中,我们创建了两个容器ilanni_mysql和ilanni_wordpress,其中- ./data:/var/lib/mysql的意思是把容器中的/var/lib/mysql目录映射到本地的data目录下。 - ./alivv.txt:/var/www/html/alivv.txt意思是把本地的alivv.txt文件挂载到容器为/var/www/html/alivv.txt文件。 - "33033:3306"意思是把容器中的3306端口映射为本地33033端口。 depends_on意思是一个容器依赖与另外一个容器。 docker-compose.yml文件编写完毕后,我们就可以启动容器了。使用如下命令: docker-compose up -d docker ps 通过上图我们可以很明显的看出,ilanni_mysql和ilanni_wordpress这个容器已经创建完毕。 PS:上述docker-compose.yml文件相关的环境变量中,我们都可以在对应docker镜像中看到对应的函数。 mysql镜像的对应变量,可以通过如下连接进行查看: https://hub.docker.com/r/library/mysql/ wordpress镜像的对应变量,可以通过如下连接进行查看: https://hub.docker.com/r/library/wordpress/ 五、导入wordpress备份数据 通过上述章节,我们可以看到ilanni_mysql容器已经正常启动了。 现在我们把wordpress备份的数据导入到新的数据库中,使用navicat进行数据传输如下: 通过上图,我们可以看到wordpress数据已经被恢复到新的数据库ilanni_mysql中了。 其他的备份数据,我们只需要复制到对应的目录下即可。 六、启动容器 其实我们在前面已经启动了容器,之所以我们再次说要启动容器,是因为我们在第五章节中刚刚把原来备份的数据恢复到新的环境中。 现在我们只需要重启容器即可,使用如下命令: docker-compose restart 现在我们来访问下刚刚恢复数据后的wordpress,如下: 通过上图,我们可以看出wordpress已经全部迁移过去了。 七、配置iptables规则 因为没有启用firewalld服务,所以这个牵涉到有关iptables规则的配置。 下面是正确配置的iptables规则,如下: cat /etc/sysconfig/iptables *nat :PREROUTING ACCEPT [263:15384] :INPUT ACCEPT [135:7704] :OUTPUT ACCEPT [104:6272] :POSTROUTING ACCEPT [232:13952] :DOCKER - [0:0] -A PREROUTING -m addrtype --dst-type LOCAL -j DOCKER -A OUTPUT ! -d 127.0.0.0/8 -m addrtype --dst-type LOCAL -j DOCKER -A POSTROUTING -s 172.17.0.1/16 ! -o docker0 -j MASQUERADE COMMIT *filter :INPUT ACCEPT [0:0] :FORWARD ACCEPT [0:0] :OUTPUT ACCEPT [0:0] :DOCKER - [0:0] -A INPUT -i br-eaa791e079d2 -j ACCEPT -A FORWARD -o br-eaa791e079d2 -j DOCKER -A FORWARD -o br-eaa791e079d2 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT -A FORWARD -i br-eaa791e079d2 ! -o br-eaa791e079d2 -j ACCEPT -A FORWARD -i br-eaa791e079d2 -o br-eaa791e079d2 -j ACCEPT -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT -A INPUT -p icmp -j ACCEPT -A INPUT -i lo -j ACCEPT -A INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT -A INPUT -p tcp -m state --state NEW -m tcp --dport 22022 -j ACCEPT -A INPUT -j REJECT --reject-with icmp-host-prohibited -A FORWARD -j REJECT --reject-with icmp-host-prohibited COMMIT 上述iptables规则中,我们需要关注nat规则和filter规则,对于nat规则中我们只需要关注POSTROUTING中ip地址即可。 该ip地址就是docrer0网卡的ip地址,我们可以通过ip a命令进行查看,如下: ip add 对于filter规则中,需要我们关注如下规则: :DOCKER - [0:0] -A FORWARD -o br-d63b827b6fc9 -j DOCKER -A FORWARD -o br-d63b827b6fc9 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT -A FORWARD -i br-d63b827b6fc9 ! -o br-d63b827b6fc9 -j ACCEPT -A FORWARD -i br-d63b827b6fc9 -o br-d63b827b6fc9 -j ACCEPT 其中br-d63b827b6fc9为docker所在机器的桥接网卡地址,如果docker所在机器有多块网卡的话,我们可以通过登录进入docker容器查看ip地址,就可以得到该容器运行时所使用的宿主机的网卡。 示例如下: docker exec -it ilanni_mysql /bin/bash ip a 八、配置wordpress上传图片权限 按照上述步骤迁移完毕后,在发布文章时,你会发现wordpress提示你没有上传图片的权限。 这个应该是wordpress镜像的一个bug,需要我们修改wordpress镜像的upload目录的权限,如下: docker exec -it ilanni_wordpress /bin/bash chown www-data:www-data -R wp-content/uploads/ 本文转自 烂泥行天下 51CTO博客,原文链接:http://blog.51cto.com/ilanni/1950268
实验环境 交换机 h3c S3600-28TP-SI h3c S5024E 参考文档 H3C_S3600_v1510 手册 H3C_S5000E 手册 网上其他热心网友的配置文档 ########################################################################################## 原理(重要) 为什么要划分Vlan? 传统的以太网是一个广播型网络,网络中的所有主机通过 HUB 或交换机相连,处在同一个广播域中。 HUB 是物理层设备,没有交换功能,接收的报文会向所有端口转发; 交换机是链路层设备,具备根据报文的目的 MAC 地址进行转发的能力,但在收到广播报文或未知单播报文 (报文的目的 MAC 地址不在交换机 MAC 地址表中)时,也会向除报文进入端口之外的所有端口转发, 为解决以太网交换机在 LAN 中无法限制广播的问题,出现了 VLAN(Virtual LocalArea Network,虚拟局域网)技术。 VLAN把一个物理上的LAN划分成多个逻辑上的LAN,每个VLAN是一个广播域。VLAN内的主机间通信就和在一个LAN内一样,而不同VLAN内的主机不能直接通信。 Vlan优点 与传统以太网相比,VLAN 具有如下的优点: 广播被限制在一个 VLAN 内,节省了带宽,提高了网络处理能力。 增强了 LAN 的安全性。VLAN 间不能直接通信,如果要访问需要通过路由器或三层交换机等三层设备。 Vlan原理 要使交换机能够分辨不同 VLAN 的报文,需要在报文中添加标识 VLAN 的字段。由于交换机工作在第二层, 只能对报文的数据链路层封装进行识别。因此,如果添加识别字段,也需要添加到数据链路层封装中。IEEE 于 1999 年颁布了用以标准化 VLAN 实现方案的 IEEE 802.1Q 协议标准草案,对带有 VLAN 标识的报文结构进行了统一规定。 传统以太网帧封装格式 |DA&SA|Type|#####DATA######| DA表示目的MAC地址,SA表示源MAC地址,TYPE表示协议类型,DATA表示数据。 IEEE 802.1Q 协议规定在目的 MAC 地址和源 MAC 地址之后封装 4 个字节的 VLAN Tag,用以标识 VLAN 的相关信息。 |DA&SA|Vlan Tag;TPID;Prioriy;CFI;Vlan ID;|TYPE|#####DATA######| 重要 VLAN ID VLAN ID 标识该报文所属 VLAN 的编号,长度为 12bit,取值范围为 0~4095。 由于 0 和 4095 通常不使用,所以 VLAN ID 的取值范围一般为 1~4094。 交换机利用 VLAN ID 来识别报文所属的 VLAN,当接收到的报文不携带 VLAN Tag时,交换机会为该报文封装带有 接收端口缺省 VLAN ID 的 VLAN Tag,将报文划分到接收端口的缺省 VLAN 中传输。 以太网端口 以太网端口链路类型有三种: Access 类型:端口只能属于1 个VLAN,一般用于连接计算机; Trunk 类型:端口可以属于多个VLAN,可以接收和发送多个VLAN 的报文,一般用于交换机之间的连接; Hybrid 类型:端口可以属于多个VLAN,可以接收和发送多个VLAN 的报文,可以用于交换机之间连接,也可以用于连接用户的计算机。 用户可以将当前以太网端口加入到指定的 VLAN 中。执行该配置以后,以太网端口 就可以转发指定 VLAN 的报文,从而实现本交换机上的 VLAN 与对端交换机上相同VLAN 的互通。 trunk类型,可以同时承载多个VLAN通过,只允许默认VLAN不打标,access只能承载单个VLAN,hybrid,可以同时承载多个VLAN通过,允许多个VLAN不打标。(在端口模式)命令格式: port link-type { access | trunk | hybrid } 缺省值:缺省为关闭vlan trunk功能 通过TRUNK口可以实现不同交换机上的相同VLAN的互通,可以通过多个VLAN的流量 ######################################################################################## 命令行视图相关 用户视图 <H3C> #连接交换机后进入用户视图 系统视图 <H3C>system-view #进入系统视图 [H3C] #当前为系统视图 vlan视图 [H3C]vlan 2 #进入vlan视图 [H3C-Vlan2] #当前为vlan视图 vlan接口视图 [H3C-Vlan2]quit #返回到系统视图 [H3C]interface vlan-interface 2 #进入vlan接口视图 [H3C-Vlan-interface2] #当前为vlan接口视图 [H3C-Vlan-interface2]quit #返回到系统视图 以太网端口视图 [H3C]interface GigabitEthernet 0/1 #进入端口视图 [H3C-GigabitEthernet0/1] #当前为端口视图 ############################################################################################ 帮助相关 任一视图下,键入 ? 获取该视图下所有的命令及其简单描述 <H3C>? debugging Enable system debugging functions display Display current system information ping Ping function quit Exit from current command view reboot Reset switch reset Reset operation save Save current configuration system-view Enter the system view undo Cancel current setting 键入一命令,后接以空格分隔的“?”,如果该命令行位置有关键字,则列出全部关键字及其简单描述。 <H3C>ping ? -c Specify the number of echo requests to send -s Specify the number of data bytes to send X.X.X.X Destination IP address 键入命令的某个关键字的前几个字母,按下<Tab>键,如果以输入字母开头的关键字唯一,则可以显示出完整的关键字 <H3C>pi? ping ########################################################################################### Vlan 相关 创建并进入vlan视图 或删除 vlan vlan 2 undo vlan 2 [undo vlan all] 将access端口加入指定vlan system-view/vlan 2/视图下执行 port GigabitEthernet 0/2 port GigabitEthernet 0/3 to GigabitEthernet 0/4 (3-4端口) 或者下条语句 port GigabitEthernet 0/3 GigabitEthernet 0/4 将access端口从 vlan 删除 system-view/vlan 2/视图下执行 undo port GigabitEthernet 0/2 vlan 3/视图下执行 undo port GigabitEthernet 0/3 to GigabitEthernet 0/6 创建并进入vlan接口视图 interface Vlan-interface 2 配置vlan接口 IP地址 system-view/vlan 2/接口视图下执行 ip address 192.168.9.1 255.255.255.0 vlan接口 指定网关。 ip gateway 192.168.9.1 配置管理的VLAN,缺省是VLAN 1 management-vlan 3 #指定vlan 3 为管理的vlan ip route-static 0.0.0.0 0.0.0.0 192.168.0.2 #增加一条缺省路由 显示vlan 设置 display vlan 3 #vlan display vlan all display interface vlan-interface 3 #vlan接口 display ip interface vlan-interface 3 #vlan ip地址 display ip routing-table [verbose] #查看路由表摘要信息,[verbose为详细信息] ################################################################################# 以太网端口相关 更改端口类型为trunk (目的 不同交换机上的相同VLAN的互通) [H3C101]interface GigabitEthernet 0/2 #进入端口视图 [H3C101-GigabitEthernet0/2]port link-type ? #? 获得 port命令帮助 access Access link-type hybrid Specify current hybrid port's characteristics trunk VLAN trunk link-type [H3C101-GigabitEthernet0/2]port link-type trunk #指定端口类型为trunk [h3c101]display interface GigabitEthernet 0/2 #显示指定端口信息 (省略了一大部分) ........................ PVID: 1 Mdi type: auto Port link-type: trunk VLAN passing : 1 (default) VLAN allowed : 1 (default) Trunk port encapsulation: IEEE 802.1q ......................... 允许其它 vlan的报文通过 Trunk 端口 [h3c101-GigabitEthernet0/2]port trunk permit vlan 200 300 #加入 vlan 200 300 [h3c101-GigabitEthernet0/2]display interface GigabitEthernet 0/2 PVID: 1 Mdi type: auto Port link-type: trunk VLAN passing : 1 (default), 200,300 VLAN allowed : 1 (default), 200,300 Trunk port encapsulation: IEEE 802.1q 配置端口 GigabitEthernet0/2 的缺省 VLAN ID 为 1 [h3c101-GigabitEthernet0/2]port trunk pvid vlan 1 ################################################################################# 用户相关 # 设置 telnet 用户密码 [H3C]user-interface vty 0 [H3C-vty0]set authentication password dongnan 设置web用户名与密码 [H3C]localuser admin admin 1 显示当前用户配置 [H3C]display user-interface Idx Type Tx/Rx 0 AUX 0 9600 + 1 VTY 0 2 VTY 1 + 3 WEB 0 4 WEB 1 5 WEB 2 6 WEB 3 + : Current user-interface is active. F : Current user-interface is active and work in async mode. Idx : Absolute index of user-interface. Type : Type and relative index of user-interface. ############################################################### 错误相关 [H3C]interface vlan-interface 300 Cannot set management-vlan different with L3 interface vlan! 先删除管理 VLAN 接口 undo interface vlan-interface 1 管理VLAN要删除掉. 默认是VLAN 1. undo management-vlan 再添加新管理VLAN ID management-vlan 300 再次添加vlan接口 interface vlan-interface 300 ip地址 ip address 192.168.5.101 255.255.255.0 网关 ip gateway 192.168.5.1 HW01_0.xy-yd-3526 : 这是交换机的名称 IP address 192.168.192.168 collision detected, sourced by 0013-d47a-46a9 on Ethernet0/7 of VLAN6 and 0010-e537-fe72 on Ethernet0/7 of VLAN6: 这是指两个ip地址冲突. 具体在vlan6里, 7号端口下某个交换机上接的2台电脑ip冲突了. 两台mac分别是,0013-d47a-46a9,0010-e537-fe72. #Apr 5 03:38:28:058 2000 H3C ARP/5/DUPIP:- 1 -IP address 192.168.2.33 collision detected, sourced by 001b-b14e-cd44 on Ethernet1/0/2 of VLAN20 and d485-64b5-d6 e2 on Ethernet1/0/2 of VLAN20 %Apr 5 03:28:30:612 2000 H3C PTVL/5/WARNING:- 1 -The link partner of Ethernet1/ 0/15 may be bad,sending lots of error packets ! 该告警的含义为,对端设备端口可能出现故障,发送了大量的错误包过来,会影响业务,建议检查两边的端口协商是否一致,如果不一致,调整两边端口协商模式,如果一致,建议更换端口。 看到这些信息后,不要重启设备,收集如下信息: dis int g1/0/25 //显示3次这个端口的完整信息。 #################################################################################### 注 意 华为的三层交换机(以S3500系列VRP3.1为例)上要各个VLAN间通信,只需要在VLAN接口视图(注意:不是VLAN视图)下给VLAN配置 IP地址,然后把该VLAN所属的端口相连设备的默认网关设成是该VLAN的iP就可以了,不需要再做其它设置。各个VLAN之间配了IP地址以后,就相当于给三层交换机路由接口配置了IP地址,各个接口都是直连到三层交换机上,就是直连路由,可以直接发现的,不用再配路由协议。 华为三层交换机上进行VLAN的配置,主要就是创建VLAN,端口划分,三层VLAN接口地址配置,静态路由或是RIP协议配置。 添加一个VLAN后,路由表里会默认增加2条Direct路由? 但是如果这个vlan下没有其他网络设备,比如没插网线,那这条direct的路由就不会有,插上就有了(这个折磨了我好长时间) 192.168.9.0/24 DIRECT 0 0 192.168.9.1 Vlan-interface90 192.168.9.1/32 DIRECT 0 0 127.0.0.1 InLoopBack0 配置 vlan 接口之前,首先要创建vlan,在配置管理 vlan 之前,首先要创建vlan S5024E(二层交换机) 任何时刻只能有一个 VLAN 对应的 VLAN 接口可以设置 IP 地址, VLAN 即为管理 VLAN。 该如果您想对 S5000E 进行远程管理,必须设置 S5000E 管理 VLAN 接口的 IP 地址。 三种类型的端口可以共存在一台设备上,但Trunk 端口和Hybrid 端口之间不能直接 切换,只能先设为Access 端口,再设置为其他类型端口。例如:Trunk 端口不能直 接被设置为Hybrid 端口,只能先设为Access 端口,再设置为Hybrid 端口。 #################################################################################### 一些列子 华为三层交换机配置实例一例 服务器1双网卡,内网IP:192.168.0.1,其它计算机通过其代理上网 PORT1属于VLAN1 PORT2属于VLAN2 PORT3属于VLAN3 VLAN1的机器可以正常上网 配置VLAN2的计算机的网关为:192.168.1.254 配置VLAN3的计算机的网关为:192.168.2.254 即可实现VLAN间互联 如果VLAN2和VLAN3的计算机要通过服务器1上网 则需在三层交换机上配置默认路由 系统视图下:ip route-static 0.0.0.0 0.0.0.0 192.168.0.1 然后再在服务器1上配置回程路由 进入命令提示符 route add 192.168.1.0 255.255.255.0 192.168.0.254 route add 192.168.2.0 255.255.255.0 192.168.0.254 这个时候vlan2和vlan3中的计算机就可以通过服务器1访问internet了~ 命令如下: 一、组网需求: 交换机配置了4个VLAN,分别为VLAN1,VLAN2,VLAN3,VLAN4,要求VLAN1可以与VLAN2,3,4互访,但是VLAN2,3,4之间不能互访,用Hybrid端口属性实现此功能。 二、组网图: 无 三、配置步骤: 1. 创建VLAN2 [Quidway]vlan 2 2. 创建VLAN3 [Quidway-vlan2]vlan 3 3. 创建VLAN4 [Quidway-vlan3]vlan 4 4. 进入端口Ethernet1/0/1 [Quidway-vlan4] interface Ethernet1/0/1 5. 将端口设置为hybrid模式 [Quidway-Ethernet1/0/1]port link-type hybrid 6. 设置端口pvid为1 [Quidway-Ethernet1/0/1]port hybrid pvid vlan 1 7. 允许VLAN1,2,3,4不打标签通过 [Quidway-Ethernet1/0/1]port hybrid vlan 1 to 4 untagged 8. 进入端口Ethernet1/0/2 [Quidway-Ethernet1/0/1]interface Ethernet1/0/2 9. 将端口设置为hybrid模式 [Quidway-Ethernet1/0/2]port link-type hybrid 10. 设置端口pvid为2 [Quidway-Ethernet1/0/2]port hybrid pvid vlan 2 11. 允许VLAN1,2不打标签通过 [Quidway-Ethernet1/0/2]port hybrid vlan 1 to 2 untagged 12. 进入端口Ethernet1/0/3 [Quidway-Ethernet1/0/2]interface Ethernet1/0/3 13. 将端口设置为hybrid模式 [Quidway-Ethernet1/0/3]port link-type hybrid 14. 设置端口pvid为3 [Quidway-Ethernet1/0/3]port hybrid pvid vlan 3 15. 允许VLAN1,3不打标签通过 [Quidway-Ethernet1/0/3]port hybrid vlan 1 3 untagged 16. 进入端口Ethernet1/0/4 [Quidway-Ethernet1/0/3]interface Ethernet1/0/4 17. 将端口设置为hybrid模式 [Quidway-Ethernet1/0/4]port link-type hybrid 18. 设置端口pvid为4 [Quidway-Ethernet1/0/4]port hybrid pvid vlan 4 19. 允许VLAN1,4不打标签通过 [Quidway-Ethernet1/0/4]port hybrid vlan 1 4 untagged 四、配置关键点: 1. 利用交换机以太网端口的Hybrid特性,可以实现PVLAN的功能。 2. 采用Hybrid属性实现的PVLAN功能和PVLAN的工作机制存在较大差异,上述情况只适用于网络流量,网络用户较少的应用 #update 20130305 huawei 华为交换机基本命令表 本文转自 dongnan 51CTO博客,原文链接: http://blog.51cto.com/dngood/601873