
测试群:248249896
暂时未有相关通用技术能力~
阿里云技能认证
详细说明每次登录SSH时总是要停顿等待一会儿才能连接上,,这是因为OpenSSH服务器有一个DNS查找选项UseDNS默认情况下是打开的。 UseDNS 选项打开状态下,当通过终端登录SSH服务器时,服务器端先根据客户端的IP地址进行DNS PTR反向查询出客户端的主机名,然后根据查询出的客户端主机名进行DNS正向A记录查询,验证与其原始IP地址是否一致,这是防止客户端欺骗的一种措施,但一般我们的是动态IP不会有PTR记录,打开这个选项没什么用,不如关闭。 通过编辑sshd_config配置文件可将其关闭: # vi /etc/ssh/sshd_config 找到:#UseDNS yes 在下方输入:UseDNS no 保存退出然后重启ssh服务: # service sshd restart 即可。
在实际测试工作过程中,有时因为生产环境已有历史数据原因,需要测试环境数据id从某个值开始递增,此时,我们需要修改数据库中自增ID起始值,下面以MySQL为例: 表名:users; 建表时添加: create table users(id int auto_increment primary key,666);表已创建,修改: alter table users add id int auto_increment primary key; #将自增字段设置为primary keyalter table users AUTO_INCREMENT=10000;
1 #!/usr/bin/env python 2 # -*- coding: utf-8 -*- 3 #http://www.cnblogs.com/liu-ke/ 4 import wmi 5 import os 6 import sys 7 import platform 8 import time 9 10 def sys_version(): 11 c = wmi.WMI () 12 #获取操作系统版本 13 for sys in c.Win32_OperatingSystem(): 14 print "Version:%s" % sys.Caption.encode("UTF8"),"Vernum:%s" % sys.BuildNumber 15 print sys.OSArchitecture.encode("UTF8")#系统是32位还是64位的 16 print sys.NumberOfProcesses #当前系统运行的进程总数 17 18 def cpu_mem(): 19 c = wmi.WMI () 20 #CPU类型和内存 21 for processor in c.Win32_Processor(): 22 #print "Processor ID: %s" % processor.DeviceID 23 print "Process Name: %s" % processor.Name.strip() 24 for Memory in c.Win32_PhysicalMemory(): 25 print "Memory Capacity: %.fMB" %(int(Memory.Capacity)/1048576) 26 27 def cpu_use(): 28 #5s取一次CPU的使用率 29 c = wmi.WMI() 30 while True: 31 for cpu in c.Win32_Processor(): 32 timestamp = time.strftime('%a, %d %b %Y %H:%M:%S', time.localtime()) 33 print '%s | Utilization: %s: %d %%' % (timestamp, cpu.DeviceID, cpu.LoadPercentage) 34 time.sleep(5) 35 36 def disk(): 37 c = wmi.WMI () 38 #获取硬盘分区 39 for physical_disk in c.Win32_DiskDrive (): 40 for partition in physical_disk.associators ("Win32_DiskDriveToDiskPartition"): 41 for logical_disk in partition.associators ("Win32_LogicalDiskToPartition"): 42 print physical_disk.Caption.encode("UTF8"), partition.Caption.encode("UTF8"), logical_disk.Caption 43 44 #获取硬盘使用百分情况 45 for disk in c.Win32_LogicalDisk (DriveType=3): 46 print disk.Caption, "%0.2f%% free" % (100.0 * long (disk.FreeSpace) / long (disk.Size)) 47 48 def network(): 49 c = wmi.WMI () 50 #获取MAC和IP地址 51 for interface in c.Win32_NetworkAdapterConfiguration (IPEnabled=1): 52 print "MAC: %s" % interface.MACAddress 53 for ip_address in interface.IPAddress: 54 print "ip_add: %s" % ip_address 55 print 56 57 #获取自启动程序的位置 58 for s in c.Win32_StartupCommand (): 59 print "[%s] %s <%s>" % (s.Location.encode("UTF8"), s.Caption.encode("UTF8"), s.Command.encode("UTF8")) 60 61 62 #获取当前运行的进程 63 for process in c.Win32_Process (): 64 print process.ProcessId, process.Name 65 66 def main(): 67 sys_version() 68 cpu_mem() 69 #disk() 70 #network() 71 #cpu_use() 72 73 if __name__ == '__main__': 74 main() 75 print platform.system() 76 print platform.release() 77 print platform.version() 78 print platform.platform() 79 print platform.machine() 注:转载需注明出处及作者。 流柯
Python3.3以上的版本通过venv模块原生支持虚拟环境,可以代替之前的virtualenv。 该venv模块提供了创建轻量级“虚拟环境”,提供与系统Python的隔离支持。每一个虚拟环境都有其自己的Python二进制(允许有不同的Python版本创作环境),并且可以拥有自己独立的一套Python包。 注意:python3.3中使用”venv”命令创建的环境不包含”pip”,需进行手动安装。Python3.4中改进了这一缺陷。 创建虚拟环境 1 python -m venv myvenv 此命令会在当前目录下生成一个名为myvenv的目录,myenv也是创建的虚拟环境名。 激活环境: /Scripts/activate.bat 退出环境: /Scripts/deactivate.bat 附: venv使用参数: 1 usage: venv [-h] [--system-site-packages] [--symlinks] [--clear] 2 [--upgrade] [--without-pip] ENV_DIR [ENV_DIR ...] 3 4 Creates virtual Python environments in one or more target directories. 5 6 positional arguments: 7 ENV_DIR A directory to create the environment in. 8 9 optional arguments: 10 -h, --help show this help message and exit 11 --system-site-packages Give access to the global site-packages dir to the 12 virtual environment. 13 --symlinks Try to use symlinks rather than copies, when symlinks 14 are not the default for the platform. 15 --copies Try to use copies rather than symlinks, even when 16 symlinks are the default for the platform. 17 --clear Delete the environment directory if it already exists. 18 If not specified and the directory exists, an error is 19 raised. 20 --upgrade Upgrade the environment directory to use this version 21 of Python, assuming Python has been upgraded in-place. 22 --without-pip Skips installing or upgrading pip in the virtual 23 environment (pip is bootstrapped by default) 注:转载需注明出处及作者。 流柯
脚本开发环境: loadrunner11.0 jdk1.6.32_x86_32 脚本开发 1.选择JavaVuser协议 2.配置java环境(Vuser--RunTime Settings) 3.开发javavuser脚本 /* * LoadRunner Java script. (Build: _build_number_) * * Script Description: JavaVuser访问页面 * * creator:jeffsui * * Create Time:2015-09-28 * */ import java.io.InputStream; import java.io.OutputStreamWriter; import java.net.URL; import java.net.URLConnection; import lrapi.lr; public class Actions { public int init() throws Throwable { return 0; }//end of init public int action() throws Throwable { /***访问首页事务*/ lr.start_transaction("访问poptest首页"); String serverUrl="http://www.poptest.cn/";//请求页面url路径 OutputStreamWriter out =null; try { URL url =new URL(serverUrl); URLConnection conn = url.openConnection();.//建立连接 conn.setDoInput(true); conn.setDoOutput(true); conn.setRequestProperty("Content-Type","UTF-8");//设置请求字符编码 out=new OutputStreamWriter(conn.getOutputStream(),"UTF-8");//设置回应字符编码 out.flush(); out.close(); InputStream in =conn.getInputStream(); byte[] buffer= new byte[in.available()]; in.read(buffer); System.out.println(new String(buffer)); } catch (Exception e ) { e.printStackTrace(); }finally{ if(out!=null){ try { out.close(); } catch (Exception e ) { e.printStackTrace(); } } } lr.end_transaction("访问poptest首页", lr.AUTO); return 0; }//end of action public int end() throws Throwable { return 0; }//end of end } 4.编译 5.执行脚本 poptest经验分享: (1)loadrunner11只支持32位的jdk (2)RuntimeSettings里只是加载了基本jdk,如果需要加载其他第三方的jar包请在JavaFunction中加载 (3)JavaVuser的执行效率取决于你的Java代码。 注:转载需注明出处及作者。 流柯
背景: 1.当通过JMeter的图像化界面运行性能压测或者场景时候,JMeter界面很容易导致界面卡死或者无响应的情况(20个线程数就会卡死) 现象如下: 解决方案: jmeter -n -t D:\apache-jmeter-3.0\bin\log.jmx -l D:\apache-jmeter-3.0\bin\log.jtl 此时线程数设置大一点,也不会卡死 2.当调试脚本或者运行场景时候,需要不断的调整线程数或者持续运行时间时候,需要先打开GUI界面,修改如下参数并保存 解决方案: 1.指定运行多少线程 我们知道JMeter测试计划在运行Sampler之前先加载运行属性(jmeter.properties,system.properties等),那么我们可以借助属性来完成。 当然了,我们也不会傻到去修改这些配置文件,这多麻烦。JMeter提供了方法可以动态修改属性,在命令行使用 -J 来指定JMeter Properties 使用__P() 函数来获取命令中指定的属性值。 实例如下: jmeter -JthreadNum=20 -Jtime=300 -n -t D:\apache-jmeter-3.0\bin\log.jmx -l D:\apache-jmeter-3.0\bin\log.jtl jmeter.bat -JthreadCount=2 -Jcycle=2 -n -t log.jmx -l log.jtl threadNum=2为log.jmx测试计划要指定的线程数 -Jcycle=2为log.jmx测试计划要指定的每个线程的迭代次数 -Jtime=10为log.jmx测试计划要指定的持续运行时间 在log.jmx测试计划中用${__P(threadNum,)}来获取threadNum的值;${__P(cycle,)}来获取cycle的值,${__P(time,)}来获取time的值 运行效果如下: 拓展知识: 如果访问的目标地址变化了,端口也变化了,重新指定: JMeter 命令行通过-D来指定System Properties,类似于Jdk中我们用-D来指定一些系统属性,比如开启JMX远程监控。 在JMeter脚本中我们用__property()函数来获取,比如-Durl=www.baidu.com在测试计划中用${__property(url,,)}来获取 运行命令如下: jmeter.bat -JthreadCount=2 -Jcycle=2 -Durl=www.baidu.com -Dport=80 -n -t baidu.jmx -l baidu.jtl 脚本如下: 如上使用-J -D在运行前动态设置属性,可以用来控制测试计划的执行,在非GUI方式运行时还是比较方便的。 自然性能测试自动化时我们可以利用这些命令行参数来动态指定属性,不用再修改脚本了。 注:转载需注明出处及作者。 流柯
在使用Loadrunner录制和回放时有时会出现乱码,从而导致脚本运行失败,这让我们很难定位脚本问题所在。 1、乱码产生的原因 1)loadrunner工具使用的是UTF-8编码,但被测系统使用的是GBK,GB18030等编码 2)我们的被测系统使用的是utf-8编码 以上可以看出,产生乱码的情况可能有两种情况: 脚本录制过程产生乱码 脚本运行过程中因编码不一致产生乱码 2、针对产生乱码的两种情况对应解决方法 1)脚本录制过程中产生乱码 当系统和工具的编码不一致,此时通过修改工具设置,使其适应被测系统 解决方法: Tools----->Recording Options(Ctrl +F7)----->选择advanced----->选择support charset 勾选UTF-8 2、运行过程中产生乱码 Vuser----->run-time-setting ------>preferences ----->options ----general----convert from/to UTF-8 如果被测软件使用的是UTF-8建议选择1 注:转载需注明出处及作者。 流柯
一.Zabbix简介 zabbix是一个基于WEB界面的提供分布式系统监视以及网络监视功能的企业级的开源解决方案。zabbix由zabbix server与可选组件zabbix agent两部分组成。 zabbix server可以通过SNMP,zabbix agent,ping,端口监视等方法提供对远程服务器/网络状态的监视。 zabbix agent需要安装在被监视的目标服务器上,它主要完成对硬件信息或与操作系统有关的内存,CPU等信息的收集。 zabbix的主要特点: - 安装与配置简单,学习成本低 - 支持多语言(包括中文) - 免费开源 - 自动发现服务器与网络设备 - 分布式监视以及WEB集中管理功能 - 可以无agent监视 - 用户安全认证和柔软的授权方式 - 通过WEB界面设置或查看监视结果 - email等通知功能等 Zabbix主要功能: - CPU负荷 - 内存使用 - 磁盘使用 - 网络状况 - 端口监视 - 日志监视 官方也提供了安装资料:http://www.zabbix.com/wiki/howto/monitor 二.Zabbix安装 2.1 zabbix WEB环境搭建 zabbix需要LAMP or LNMP环境支持,此处不细讲 yum安装 yum install mysql-dev gcc net-snmp-devel curl-devel perl-DBI php-gd php-mysql php-bcmath php-mbstring php-xm 修改PHP相关参数 vi php.ini max_execution_time = 300 max_input_time = 300 memory_limit = 128M post_max_size = 32M date.timezone = Asia/Shanghai mbstring.func_overload=2 2.2 zabbix 数据库设置 给zabbix数据库授权 grant all privileges on zabbix.* to zabbix@'localhost' identified by 'password'; 2.3安装zabbix 增加zabbix用户和组 #groupadd zabbix #useradd -g zabbix -m zabbix 下载解压软件、解压 下载地址:http://www.zabbix.com/download.php #wget http://fossies.org/unix/misc/zabbix-2.0.3.tar.gz # tar -zxvf zabbix-2.0.3.tar.gz #cd zabbix-2.203 导入数据库表结构和数据 zabbix-2.0.3/database/mysql目录下面有三个SQL文件,导入(注意导入顺序) #mysql -uroot -ppassword zabbix < schema.sql #mysql -uroot -ppassword zabbix < images.sql #mysql -uroot -ppassword zabbix < data.sql 编译安装zabbix(在zabbix-2.0.3目录下执行) #./configure --prefix=/usr/local/zabbix --with-mysql --with-net-snmp --with-libcurl --enable-server --enable-agent --enable-proxy#make#make install 添加服务端口 vim /etc/services zabbix-agent 10050/tcp # Zabbix Agent zabbix-agent 10050/udp # Zabbix Agent zabbix-trapper 10051/tcp # Zabbix Trapper zabbix-trapper 10051/udp # Zabbix Trapper 添加配置文件 # mkdir -p /etc/zabbix # cp -r zabbix-2.203/conf/* /etc/zabbix/ # chown -R zabbix:zabbix /etc/zabbix 修改server配置文件,添加zabbix数据库密码vim /etc/zabbix/zabbix_server.conf LogFile=/tmp/zabbix_server.log PidFile=/tmp/zabbix_server.pid DBName=zabbix DBUser=zabbix DBPassword=123456 #指定zabbix数据库密码 ListenIP=192.168.33.12 #服务器IP地址 修改Agentd配置文件,更改HOSTNAME为本机的hostnamevim /etc/zabbix/zabbix_agentd.conf PidFile=/tmp/zabbix_agentd.pid #进程PID LogFile=/tmp/zabbix_agentd.log #日志保存位置 EnableRemoteCommands=1 #允许执行远程命令 Server=192.168.33.12#agent端的ip Hostname=client1 #必须与zabbix创建的host name相同 配置web前端php文件 # cd zabbix-2.203/frontends/ # cp -rf php /data/www/zabbix #LNMP虚拟主机目录 # chown -R zabbix:zabbix /data/www/zabbix # chmod -R 755 /data/www/zabbix 在浏览器上面访问zabbix,进行前端配置,http://ZabbixIP/zabbix,按提示下一步即可(若提示权限问题,去服务端修改文件及目录权限即可) 配置完成后进入在登录界面,默认的用户名为:Admin,密码为:zabbix(注意大小写) 三.启动zabbix服务在zabbix目录直接启动 #/usr/local/zabbix/sbin/zabbix_server start 设置开启自动启动 vi /etc/rc.d/rc.local 在文件最后添加如下内容: /usr/local/zabbix/sbin/zabbix_server start /usr/local/zabbix/sbin/zabbix_agentd start 注:转载需注明出处及作者。 流柯
原理: 1.截图(整个窗口) 2.获取此元素坐标 element = driver.find_element_by_id("xx") element.location) 3.获取此元素大小 element = driver.find_element_by_id("xx") element.size 4.根据元素坐标和元素大小确定此元素四个角坐标 5.依赖pillow,根据四角坐标提取图片并保存 案例源码: 首先pip安装pillow pip install pillow 截图: # coding:utf-8 from selenium import webdriver from PIL import Image driver = webdriver.Firefox() driver.get('http://www.baidu.com/') driver.save_screenshot('bdbutton.png') element = driver.find_element_by_id("su") print(element.location) # 打印元素坐标 print(element.size) # 打印元素大小 left = element.location['x'] top = element.location['y'] right = element.location['x'] + element.size['width'] bottom = element.location['y'] + element.size['height'] im = Image.open('bdbutton.png') im = im.crop((left, top, right, bottom)) im.save('bdbutton.png') 注:转载需注明出处及作者。 流柯
Visual GC提示"不受此JVM支持“,如果想使用这个插件,就需要配置jstatd连接方式,下面来看jstatd的配置; 1.配置安全策略文件路径$JAVA_HOME/jre/lib/security/java.policy在文件末位的 }; 前添加permission java.security.AllPermission; 2.启动jstatd 注意:是在被监控机器启动 cd $JAVA_HOME/bin./jstatd -J-Djava.security.policy=all.policy & 启动后会开启注册端口1099和一个随机的连接端口,注册端口也可通过-p参数指定,如./jstatd -J-Djava.security.policy=all.policy -p 10003 & 3.设置防火墙除了把1099添加到防火墙规则外,还需要找到另外一个随机端口,也加入到规则中执行netstat -anp | grep *jstatd vi /etc/sysconfig/iptables 在-A INPUT -j REJECT --reject-with icmp-host-prohibited前加入 -A INPUT -p tcp -m state --state NEW -m tcp --dport 1009 -j ACCEPT 4.测试 启动VisualVM,因为在配置JMX时已经添加过服务器节点,如果配置正确,通常VisualVM会自动检测到jstatd连接并添加节点 如果没有自动添加,可以检查端口是否能连通并尝试手动添加连接 注:转载需注明出处及作者。 流柯
执行Python出现LookupError: unknown encoding: cp65001错误 dos下执行以下命令即可 chcp 1252 以上。 注:转载需注明出处及作者。 流柯
Selenium通过window_handles获取当前窗口句柄,进行页面元素操作 切换回原窗口句柄,进行元素操作 代码如下:(python版) __author__ = 'liuke' import unittest,time,re from selenium import webdriver class Untitled(unittest.TestCase): def setUp(self): self.driver = webdriver.Chrome() self.driver.implicitly_wait(10) self.url = "http://www.baidu.com" def test_Untitled (self): driver = self.driver driver.get(self.url) now_handle = driver.current_window_handle #获取当前窗口句柄 print (now_handle) #输出当前获取的窗口句柄 driver.find_element_by_id("kw").send_keys("流柯") driver.find_element_by_id("su").click() driver.find_element_by_partial_link_text("www.cnblogs.com/liu-ke/ ").click() #点击链接跳转新标签页 time.sleep(2) all_handles = driver.window_handles #获取所有窗口句柄 for handle in all_handles: if handle != now_handle: print (handle) #输出待选择的窗口句柄 driver.switch_to_window(handle) #绑定 driver.find_element_by_id("blog_nav_sitehome").click() time.sleep(5) driver.close() #关闭当前窗口 time.sleep(3) print (now_handle) #输出主窗口句柄 driver.switch_to_window(now_handle) #返回主窗口 time.sleep(2) driver.find_element_by_id("kw").clear() driver.find_element_by_id("kw").send_keys("12306") driver.find_element_by_id("su").click() time.sleep(10) def tearDown(self): self.driver.quit() #pass if __name__ == "__main__": unittest.main() 以上。 注意driver与新窗口的绑定。 注:转载需注明出处及作者。 流柯
1:配置executor属性 打开/conf/server.xml文件,在Connector之前配置一个线程池: <Executor name="tomcatThreadPool" namePrefix="tomcatThreadPool-" maxThreads="1000" maxIdleTime="300000" minSpareThreads="200"/> 重要参数说明: name:共享线程池的名字。这是Connector为了共享线程池要引用的名字,该名字必须唯一。默认值:None; namePrefix:在JVM上,每个运行线程都可以有一个name 字符串。这一属性为线程池中每个线程的name字符串设置了一个前缀,Tomcat将把线程号追加到这一前缀的后面。默认值:tomcat-exec-; maxThreads:该线程池可以容纳的最大线程数。默认值:200; maxIdleTime:在Tomcat关闭一个空闲线程之前,允许空闲线程持续的时间(以毫秒为单位)。只有当前活跃的线程数大于minSpareThread的值,才会关闭空闲线程。默认值:60000(一分钟)。 minSpareThreads:Tomcat应该始终打开的最小不活跃线程数。默认值:25。 2:配置Connector <Connector executor="tomcatThreadPool" port="8080" protocol="org.apache.coyote.http11.Http11NioProtocol" connectionTimeout="20000" redirectPort="8443" minProcessors="5" maxProcessors="75" acceptCount="1000"/> 重要参数说明: executor:表示使用该参数值对应的线程池; minProcessors:服务器启动时创建的处理请求的线程数; maxProcessors:最大可以创建的处理请求的线程数; acceptCount:指定当所有可以使用的处理请求的线程数都被使用时,可以放到处理队列中的请求数,超过这个数的请求将不予处理。 注:转载需注明出处及作者。 流柯
python爬虫遇到https站点InsecureRequestWarning警告解决方案 加三行代码即可 from requests.packages.urllib3.exceptions import InsecureRequestWarning,InsecurePlatformWarningrequests.packages.urllib3.disable_warnings(InsecureRequestWarning)requests.packages.urllib3.disable_warnings(InsecurePlatformWarning) 以上。 注:转载需注明出处及作者。 流柯
在做UI自动化的过程中,有时需要由一个窗口跳转到另一个窗口,这时直接去定位页面元素,可能会出现问题,这时,我们需要将driver与新的窗口进行绑定。 完整代码如下:(python版) #coding=utf-8 import os from selenium import webdriver import time chrome = 'C:\Program Files (x86)\Google\Chrome\Application\chromedriver.exe' os.environ["webdriver.chrome.driver"] = chrome driver = webdriver.Chrome(chrome) driver.get('http://www.baidu.com') #获取当前窗口的句柄 currentWin = driver.current_window_handle #跳转到另一个新页面 driver.find_element_by_xpath("//p[@id='nv']/a[3]").click() time.sleep(1) #获取所有窗口的句柄 handles = driver.window_handles for i in handles: if currentWin == i: continue else: #将driver与新的页面绑定起来 driver = driver.switch_to_window(i) #在新的页面定位元素 driver.find_element_by_xpath("//div[@id='menu']/a[1]").click() time.sleep(2) driver.quit() 以上。 说明:driver是对应到一个特定的窗口的。使用switch_to_window()方法后,需要更新driver,将driver与新的窗口绑定。 注:转载需注明出处及作者。 流柯
性能测试混合场景中,我们需要组合多个业务操作到场景中来。比如有一个论坛的业务分布如下:发布新帖与回复帖子的比例为2:3,那么我们在JMeter测试计划中如何控制其比例呢? 可以通过以下两种方式解决:多线程组方式 逻辑控制器控制 多线程组方式: JMeter是用线程组来模拟虚拟用户的,JMeter支持一个计划中多个线程组。利用这个特性我们可以把发布新帖业务放在一个线程组中,回帖业务放在另外一个线程组中。通过控制线程数来达到需求的业务量的比例关系。 回帖线程组,添加90个线程;发布新帖线程组,添加60个线程,刚好是3:2。 但,,,这只能是近似的,如果这两个事务的响应时间不一样,最终完成的业务数比例也会不一样。当前线程数是在假定两个业务的响应时间一样的情况下,所以这完全是理想状况。所以,这种方式控制并不完美。 控制器控制: 如果(If)控制器可以使用表达式来做为条件,这样我们可以获取迭代次数来决定是回帖还是发新帖,比如一共3次迭代,第1次与第3次迭代时发新帖,1,2,3次迭代都会进行回帖 JMeter函数助手提供了一个“__counter”函数,可以用来获取当前的迭代次数。 如何保持3:2的比例呢? ${__counter(true,)}%2==1||${__counter(true,)}%3==0 上面__counter(true,)是获取当前迭代次数,%是取余,也就是除2余1与3整除时执行发新帖。以9次迭代为例,回帖9次,1,3,5,6,7,9 次迭代时都会发新帖,回帖刚好是6次9:6=3:23:2的比例达到。 注:转载需注明出处及作者。 流柯
URL和JDBC驱动: Datebase Driver class Database URL MySQL com.mysql.jdbc.Driver jdbc:mysql://host:port/{dbname} PostgreSQL org.postgresql.Driver jdbc:postgresql:{dbname} Oracle oracle.jdbc.driver.OracleDriver jdbc:oracle:thin:user/pass@//host:port/service Ingres (2006) ingres.jdbc.IngresDriver jdbc:ingres://host:port/db[;attr=value] MSSQL com.microsoft.sqlserver.jdbc.SQLServerDriver 或者 net.sourceforge.jtds.jdbc.Driver jdbc:sqlserver://IP:1433;databaseName=DBname 或者 jdbc:jtds:sqlserver://localhost:1433/"+"library" 以上。 注:转载需注明出处及作者。 流柯
失败事务报错信息如下, Socket closed Non HTTP response code: org.apache.http.NoHttpResponseException (the target server failed to respond) 问题原因:在JMeter下,发送http 请求时,一般都是默认选择了use keepAlive(这个是什么?看后面资料),这个是连接协议,JMeter坑就在这里,默认勾选了这个(如果不勾选的话,也不会出现问题),但其配置JMeter.properties中的时间设置默认却是注销的,也是是说,不会等待,一旦连接空闲,则立马断开了,导致我们压测中出现了事务失败的情形。 解决: 1、修改httpclient4.idletimeout=<time in ms> 设置成自己觉得合理的时间,一般可设置成10-60s(表示连接空闲10s后才会断开),注意这边单位是ms。修改完成后再次压测,错误不再有了。 2、或者直接不勾选这个(请求连接完成后就断开,新请求时就再创建) 注:转载需注明出处及作者。 流柯
1、添加HTTP信息头管理器 Content-Type application/json Accept application/json 2、添加http请求(方法、编码、路径、body) 注:转载需注明出处及作者。 流柯
PermGen space的全称是Permanent Generation space,是指内存的永久保存区域,这块内存主要是被JVM存放Class和Meta信息的,Class在被Loader时就会被放到PermGen space中,它和存放类实例(Instance)的Heap区域不同,GC(Garbage Collection)不会在主程序运行期对PermGen space进行清理,所以如果你的应用中有很多CLASS的话,就很可能出现PermGen space错误,这种错误常见在web服务器对JSP进行pre compile的时候。如果你的WEB APP下都用了大量的第三方jar, 其大小超过了jvm默认的大小(4M)那么就会产生此错误信息了。解决方法: 手动设置MaxPermSize大小 JMeter启动中的perm相关如下: if %current_minor% LEQ "8" ( rem Increase MaxPermSize if you use a lot of Javascript in your Test Plan : set PERM=-XX:PermSize=64m -XX:MaxPermSize=128m) 故推测可能是该设置没有生效的缘故(在if里面的设置) 所以,直接在外面加了这句话,然后启动OK。 set PERM=-XX:PermSize=64m -XX:MaxPermSize=128m 注:转载需注明出处及作者。 流柯
oracle性能分析入门学习中,遇到oracle数据库的性能问题,一般首要的步骤就是导出AWR的分析报告,awr报告是oracle自带的监控报告,会自带很多监控数据,那么本篇博客就是介绍如何导出awr报告 1.首先需要进入oracle用户,linux命令:su oracle,可以看到从root用户改为oracle用户 2.然后进去sql命令行 sqlplus / as sysdba 3.可以再连接,或者再测试一下 conn /as sysdba 4.进入oracle报告选项中 @?/rdbms/admin/awrrpt.sql 5.Enter value for report_type: 这个显示的意思是打印一个报告是以什么格式打印的,要么输入html,要么输入text,如果直接默认回车,这里是html 这里直接默认回车,也就是直接采用默认的html 6.Enter value for num_days: 这里的提示是让我们输出几天的报告,如果写1就输出1天,如果2就是两天 7.Enter value for begin_snap: 出入起始的快照ID,这里指的是打印出来的snap id,后面有snap started开始的时间 输入一个起始的快照,输出一个结束的快照id(本处起始id位3739,结束id位3740,也就是从22:30-22:40,中间10分钟的间隔),这样就将两个时间段内的oracle报告输出 (一般用法,性能测试时,先手工拍摄一张快照,或者调低自动快照的时间,然后执行压测脚本,再手工拍摄之类,取压测前后的快照id,这样既可导出压测期间的结果) 8.Enter value for report_name: 输入一个报告的名字 比如test.html,不输入就是默认的 9.再按exit退出命令行模式,就可以在该目录下生成一个目录报告 把这个html下载下来,用浏览器打开即可看到awr测试报告! 注:转载需注明出处及作者。 流柯
连接DB2 1、将db2数据库驱动db2java.jar、db2jcc.jar放入jmeter的lib/下,同时也要放入本地jdk目录下例如:C:\Program Files\Java\jdk1.7.0_751\jre\lib\ext db2安装目录下以linux为例/安装的目录/db2admin/sqllib/java,db2java驱动原本为zip格式,需要传入本地后改为.jar格式 2、在Jmeter中添加JDBC配置文件(JDBC Connection Configuration) 路径:右键添加——配置文件——JDBC Connection Configuration 3、在JDBC Connection Configuration中设置连接, Database URL:填入需要连接的MYSQL数据库例如:jdbc:db2://localhost:3306/test localhost为ip,3306为端口号,test为连接的数据库 (如果需要一个请求执行多条Sql语句应该写成jdbc:db2://localhost:3306/test?user=root&password=&allowMultiQueries=true) JDBC Driver class:com.ibm.db2.jcc.DB2Driver(JCC表示通过DB2jcc驱动连接) Username 与Password 输入连接时候用的用户名与密码 4、设置完成后添加JDBC Request,路径:右键添加——Sampler——JDBC Request SQL Query中输入SQL语句。 连接Mysql 1、将连接的mysql-connector-java-5.1.26-bin.jar放入jmeter的lib/下 2、在Jmeter中添加JDBC配置文件(JDBC Connection Configuration) 路径:右键添加——配置文件——JDBC Connection Configuration 3、在JDBC Connection Configuration中设置连接, Database URL:填入需要连接的MYSQL数据库例如:jdbc:mysql://localhost:3306/test localhost为ip,3306为端口号,test为连接的数据库 (如果需要一个请求执行多条Sql语句应该写成jdbc:mysql://localhost:3306/test?user=root&password=&allowMultiQueries=true) JDBC Driver class:com.mysql.jdbc.Driver Username 与Password 输入连接时候用的用户名与密码 4、设置完成后添加JDBC Request,路径:右键添加——Sampler——JDBC Request Variable Name输入连接池信息,默认输入为:MySQL SQL Query中输入SQL语句。 连接Oracle 1、Database URL:填入需要连接的Oracle数据库例如:jdbc:oracle:thin:@IP:1521:数据库名 2、JDBC Driver class:oracle.jdbc.driver.OracleDriver Username 与Password 输入连接时候用的用户名与密码 3、Validation Query:Select 1 from dual(特别注意) 注:转载需注明出处及作者。 流柯
Windows7的引导程序能够引导vhd格式的虚拟硬盘,而VirtualBox创建的虚拟硬盘文件是vdi格式的,怎么办呢? 以前要借助其他软件才能实现,但是VirtualBox早就悄悄为我们带来了一个VBoxManager.exe来转换格式。 命令如下(Windows环境,Linux版的应该也有VBoxManager这个二进制文件): VBoxManager存在于VirtualBox的安装目录下。 vmdk转换成vdi VBoxManage.exe clonehd source.vmdk target.vdi --format VDI vdi转换成vmdk VBoxManage.exe clonehd source.vdi target.vmdk --format VMDK vdi转换成vhd VBoxManage.exe clonehd source.vdi target.vhd --format VHD vmdk转vhd,vhd转vdi、vmdk的话稍微改一点参数就OK了。 需要注意的是运行完命令之后,原文件并不会被删除。 注:转载需注明出处及作者。 流柯
程序包com.sun.xml.internal.ws.spi不存在 当maven项目里面有用到JDK内部的一些类,接口(如:com.sun.xml.internal.ws.spi.ProviderImpl)等的时候,用maven编译一般会出现如下错误 [INFO] BUILD FAILURE [INFO] ------------------------------------------------------------------------ [INFO] Total time: 1.105 s [INFO] Finished at: 2017-07-05T12:45:49+08:00 [INFO] Final Memory: 21M/219M [INFO] ------------------------------------------------------------------------ [ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.1:compile (default-compile) on project test: Compilation failure [ERROR] /C:/Users/Administrator/Desktop/lk/src/main/java/com/lk/Test.java:[7,36] 程序包com.sun.xml.internal.ws.spi不存在 [ERROR] -> [Help 1] [ERROR] 解决方法如下: 添加maven-compiler-plugin插件,并且配置compilerArguments <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.7</source> <target>1.7</target> <compilerArguments> <bootclasspath>${JAVA_HOME}/jre/lib/rt.jar</bootclasspath> </compilerArguments> </configuration> </plugin> 注意: 1:这里的rt.jar需要配置正确的路径 2:如果使用的类,接口等在其他的jar里面(如tools.jar),则bootclasspath值需要配置成其他的jar 配置好之后,再编译打包,就没有问题了 注:转载需注明出处及作者。 流柯
POM的全称是“ProjectObjectModel(项目对象模型)”。 声明规范 <projectxmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0http://maven.apache.org/maven-v4_0_0.xsd"> <!--声明项目描述符遵循哪一个POM模型版本。模型本身的版本很少改变,虽然如此,但它仍然是必不可少的,这是为了当Maven引入了新的特性或者其他模型变更的时候,确保稳定性。--> <modelVersion>4.0.0</modelVersion> 基本内容 parent <!--父项目的坐标。如果项目中没有规定某个元素的值,那么父项目中的对应值即为项目的默认值。坐标包括groupID,artifactID和version。--> <parent> <!--被继承的父项目的构件标识符--> <artifactId/> <!--被继承的父项目的全球唯一标识符--> <groupId/> <!--被继承的父项目的版本--> <version/> <!--父项目的pom.xml文件的相对路径。相对路径允许你选择一个不同的路径。默认值是../pom.xml。Maven首先在构建当前项目的地方寻找父项目的pom,其次在文件系统的这个位置(relativePath位置),然后在本地仓库,最后在远程仓库寻找父项目的pom。--> <relativePath/> </parent> groupId <!- groupId在一个组织或项目中通常是特有的。例如:(大概、也许)Maven所有artifacts的groupId都使用org.apache.maven。groupId并不一定必须使用点符号,例如,JUnit项目。注意使用点符号的groupId不必与项目的包结构相同,但它是一个很好的做法。 --> <groupId>org.codehaus.mojo</groupId> artifactId <!--artifactId一般是该项目的名字。它和groupID一起标识一个唯一的项目。换句话说,你不能有两个不同的项目拥有同样的artifactID和groupID;在某个特定的groupID下,artifactID也必须是唯一的。--> <artifactId>my-project</artifactId> version <!--这是命名的最后一段。groupId:artifactId表示单个项目,但它们无法描绘具体的版本。如:我想要junit:junit项目今天第四版。version定义当前项目的版本,如:1.0(-SNAPSHOT),SNAPSHOT表示快照,说明该项目还处于开发阶段,是不稳定版本;建议version格式为:主版本.次版本.增量版本-限定版本号--> <version>1.0-SNAPSHOT</version> packaging <!--项目产生的构件类型,例如jar、war、ear、pom等等。插件可以创建他们自己的构件类型,所以前面列的不是全部构件类型。默认值jar。--> <packaging>jar</packaging> <!-- ps: groupId:artifactId:version:packaging在YouTube某些教学视频也称为UUID。 产物是如何储存在仓库中的?存放到私服库时点符号将会被解析成目录分隔符,SNAPSHOT版本在私服库中会被解析成8位日期.时分秒毫秒-序号。序号代表第几次部署。 上面的坐标将会被解析成:org/codehaus/mojo/my-project/1.0-SNAPSHOT/my-project-8位日期.时分秒毫秒-序号.jar 特例:如果你编译源代码将产物存放到本地仓库,将保持不变。 --> dependencies <!--该元素描述了项目相关的所有依赖。这些依赖组成了项目构建过程中的一个个环节。它们自动从项目定义的仓库中下载。要获取更多信息,请看项目依赖机制。--> <dependencies> <dependency> <!--依赖的groupID--> <groupId>org.apache.maven</groupId> <!--依赖的artifactID--> <artifactId>maven-artifact</artifactId> <!--依赖的版本号。可以配置成确定的版本号,也可以配置成版本号的范围。 (, )不包含 [, ]包含 例如:[3.8,4.0) 表示3.8 - 4.0的版本,但是不包含4.0 --> <version>3.8.1</version> <!--依赖类型,默认类型是jar。它通常表示依赖的文件的扩展名,但也有例外。一个类型可以被映射成另外一个扩展名或分类器。类型经常和使用的打包方式对应,尽管这也有例外。一些类型的例子:jar,war,ejb-client和test-jar。如果设置extensions为true,就可以在plugin里定义新的类型。所以前面的类型的例子不完整。--> <type>jar</type> <!--依赖的分类器。分类器可以区分属于同一个POM,但不同构建方式的构件。分类器名被附加到文件名的版本号后面。例如,如果你想要构建两个单独的构件成JAR,一个使用Java1.4编译器,另一个使用Java6编译器,你就可以使用分类器来生成两个单独的JAR构件。--> <classifier></classifier> <!--依赖范围。在项目发布过程中,帮助决定哪些构件被包括进来。欲知详情请参考依赖机制。 -compile:compile是默认的范围;如果没有提供一个范围,那该依赖的范围就是编译范 围。编译范围依赖在所有的classpath中可用,同时它们也会被打包。 -provided:provided依赖只有在当JDK 或者一个容器已提供该依赖之后才使用。例如, 如果你开发了一个web 应用,你可能在编译 classpath 中需要可用的Servlet API 来编译一个servlet,但是你不会想要在打包好的WAR 中包含这个Servlet API;这个Servlet API JAR 由你的应用服务器或者servlet 容器提供。已提供范围的依赖在编译时 (不是运行时)可用。它不具有传递性的,也不会被打包。 -runtime:runtime依赖在运行和测试系统的时候需要,但在编译的时候不需要。比如,你 可能在编译的时候只需要JDBC API JAR,而只有在运行的时候才需要JDBC驱动实 现。 -test: test范围依赖 在一般的 编译和运行时都不需要,它们只有在测试编译和测试运 行阶段可用。 -system:system范围依赖与provided类似,但是你必须显式的提供一个对于本地系统中 JAR文件的路径。这么做是为了允许基于本地对象编译,而这些对象是系统类库 的一部分。这样的构件应该是一直可用的,Maven也不会在仓库中去寻找它。如 果你将一个依赖范围设置成系统范围,你必须同时提供一个systemPath元素。注 意该范围是不推荐使用的(你应该一直尽量去从公共或定制的Maven仓库中引用 依赖)。--> <scope>test</scope> <!--仅供system范围使用。注意,不鼓励使用这个元素,并且在新的版本中该元素可能被覆盖掉。该元素为依赖规定了文件系统上的路径。需要绝对路径而不是相对路径。推荐使用属性匹配绝对路径,例如${java.home}。--> <systemPath></systemPath> <!--默认为false,即子项目默认都继承,为true,则子项目必需显示的引入。例如:假设项目A在编译时需要项目B的代码,但运行时并不需要项目B,而且我们可能并不需要所有项目都依赖项目B。--> <optional>true</optional> <!--当计算传递依赖时,从依赖构件列表里,列出被排除的依赖构件集。即告诉maven你只依赖指定的项目,不依赖项目的依赖。也可以使用通配符*排除所有依赖。此元素主要用于解决版本冲突问题.--> <exclusions> <exclusion> <artifactId>spring-core</artifactId> <groupId>org.springframework</groupId> </exclusion> </exclusions> <!--可选依赖,如果你在项目B中把C依赖声明为可选,你就需要在依赖于B的项目(例如项目A)中显式的引用对C的依赖。可选依赖阻断依赖的传递性。--> <optional>true</optional> </dependency> </dependencies> dependencyManagement <!--继承自该项目的所有子项目的默认依赖信息。这部分的依赖信息不会被立即解析,而是当子项目声明一个依赖(必须描述groupID和artifactID信息),如果groupID和artifactID以外的一些信息没有描述,则通过groupID和artifactID匹配到这里的依赖,并使用这里的依赖信息。--> <dependencyManagement> <!--参见dependencies元素--> <dependencies> <dependency> ...... </dependency> </dependencies> </dependencyManagement> modules <!--模块(有时称作子项目)被构建成项目的一部分。列出的每个模块元素是指向该模块的目录的相对路径--> <modules/> <!-- Ps:继承和模块的区别:继承父不知子,但子知父。模块父知子,但子不知父。所以在具体的项目中一般都是继承和模块融合使用。 --> properties <!--键值对,Properties可以在整个POM中使用,也可以作为触发条件(见settings.xml配置文件里profiles→properties元素的说明)。格式是<name>value</name>。--> <properties> <dept>No</dept> </properties> 编译设置 build <!--构建项目需要的信息--> <build> <!-- 预定义执行的目标或者阶段,必须和命令行的参数相同。如:jar:jar或者clean install等等。例如:defaultGoal配置clean install ,在命令行输入mvn时会自动拼接成mvn clean install。偷懒的福音啊。--> <defaultGoal>install</defaultGoal> <!-- 编译输出目录,默认值${basedir}/target(不建议修改) --> <directory>${basedir}/target</directory> <!-- 构建产物的名称,没有文件扩展名。默认值${artifactId}-${version}。 --> <finalName>${artifactId}-${version}</finalName> <!-- 单独过滤某个文件,更多内容请访问如何过滤资源文件 --> <filters> <filter>src/main/filters/filter.properties</filter> </filters> <!--这个元素描述了项目相关的所有资源路径列表,例如和项目相关的属性文件,这些资源被包含在最终的打包文件里。--> <resources> <!--这个元素描述了项目相关的资源路径--> <resource> <!-- 指定build后的resource存放的文件夹。该路径默认是basedir。通常被打包在JAR中的resources的目标路径为META-INF --> <targetPath></targetPath> <!--是否使用参数值代替参数名。如:aa=name 将my ${aa}显示为my name。true代表替换,false代表不替换。参数值取自properties元素、文件里配置的属性或者命令行的-D选项。有@aa@和${aa}俩种写法。更多内容请查看在线帮助--> <filtering>false</filtering> <!--描述存放资源的目录,该路径相对POM路径。默认值${basedir}/src/main/resources --> <directory>${basedir}/src/main/resources </directory> <!--用于指定要包括的文件。可以使用通配符*。例如**/*.xml。 --> <includes> <include>configuration.xml</include> </includes> <!--用于指定不需要包括的文件。可以使用通配符*。例如**/*.xml。如果和includes的配置冲突,excludes的优先级更高。 --> <excludes> <exclude>**/*.properties</exclude> </excludes> </resource> </resources> <!--该testResources元素块包含testResource元素。它们的定义是类似的resource 元素,仅在测试阶段使用。和resource元素唯一一点不同是testResource的默认值是${project.basedir}/src/test/resources。测试资源是不会部署。--> <testResources> <testResource> <targetPath/> <filtering/> <directory/> <includes/> <excludes/> </testResource> </testResources> <plugins> <!--plugin元素包含描述插件所需要的信息。--> <plugin> <!--插件在仓库里的groupID--> <groupId>org.apache.maven.plugins</groupId> <!--插件在仓库里的artifactID--> <artifactId>maven-jar-plugin</artifactId> <!--被使用的插件的版本(或版本范围)--> <version>2.0</version> <!--是否从该插件下载Maven扩展(例如打包和类型处理器),由于性能原因,只有在真需要下载时,该元素才被设置成enabled。--> <extensions>false</extensions> <!-- true 或 false ,这个插件的配置是否,可以继承。默认true。 --> <inherited>true</inherited> <!-- 请查阅https://maven.apache.org/pom.html#Plugins或者查阅中文版http://blog.csdn.net/tomato__/article/details/13625497 --> <configuration> <classifier>test</classifier> </configuration> <!-- 请参考dependencies元素 --> <dependencies> <dependency> <groupId/> <artifactId/> <version/> <type/> <classifier/> <scope/> <systemPath/> <exclusions> <exclusion> <artifactId/> <groupId/> </exclusion> </exclusions> <optional/> </dependency> </dependencies> <!--在构建生命周期中执行一组目标的配置。每个目标可能有不同的配置。--> <executions> <!--execution元素包含了插件执行需要的信息--> <execution> <!--执行目标的标识符,用于标识构建过程中的目标,或者匹配继承过程中需要合并的执行目标--> <id>echodir</id> <!--绑定了目标的构建生命周期阶段,如果省略,目标会被绑定到源数据里配置的默认阶段--> <phase>verify</phase> <!--配置的执行目标--> <goals> <goal>run</goal> </goals> <!--配置是否被传播到子POM--> <inherited>false</inherited> <!-- 请查阅https://maven.apache.org/pom.html#Plugins --> <configuration> <tasks> <echo>Build Dir: ${project.build.directory}</echo> </tasks> </configuration> </execution> </executions> </plugin> </plugins> <!--子项目可以引用的默认插件信息。该插件配置项直到被引用时才会被解析或绑定到生命周期。给定插件的任何本地配置都会覆盖这里的配置--> <pluginManagement> <plugins> ................. </plugins> </pluginManagement> <!--该元素设置了项目源码目录,当构建项目的时候,构建系统会编译目录里的源码。该路径是相对于pom.xml的相对路径。--> <sourceDirectory>${basedir}/src/main/java</sourceDirectory> <!--该元素设置了项目脚本源码目录,该目录和源码目录不同:绝大多数情况下,该目录下的内容会被拷贝到输出目录(因为脚本是被解释的,而不是被编译的)。--> <scriptSourceDirectory>${basedir}/src/main/scripts</scriptSourceDirectory> <!--该元素设置了项目单元测试使用的源码目录,当测试项目的时候,构建系统会编译目录里的源码。该路径是相对于pom.xml的相对路径。--> <testSourceDirectory>${basedir}/src/test/java</testSourceDirectory> <!--被编译过的应用程序class文件存放的目录。--> <outputDirectory>${basedir}/target/classes</outputDirectory> <!--被编译过的测试class文件存放的目录。--> <testOutputDirectory>${basedir}/target/test-classes</testOutputDirectory> <!--使用来自该项目的一系列构建扩展--> <extensions> <!--描述使用到的构建扩展。--> <extension> <!--构建扩展的groupId--> <groupId/> <!--构建扩展的artifactId--> <artifactId/> <!--构建扩展的版本--> <version/> </extension> </extensions> </build> reporting <!--该元素描述使用报表插件产生报表的规范。当用户执行“mvn site”,这些报表就会运行。在页面导航栏能看到所有报表的链接。--> <reporting> <!--所有产生的报表存放到哪里。默认值是${basedir}/target/site 。--> <outputDirectory>${basedir}/target/site</outputDirectory> <!--如果为true,则网站不包括默认的报表。这包括“项目信息”菜单中的报表。默认false--> <excludeDefaults>false</excludeDefaults> <!--使用的报表插件和他们的配置。--> <plugins> <!--plugin元素包含描述报表插件需要的信息--> <plugin> <!--报表插件在仓库里的groupID,默认值是 : org.apache.maven.plugins 。--> <groupId>org.apache.maven.plugins</groupId> <!--报表插件在仓库里的artifactID--> <artifactId>maven-project-info-reports-plugin</artifactId> <!--被使用的报表插件的版本(或版本范围)--> <version>2.7</version> <!--任何配置是否被传播到子项目,默认true--> <inherited>true<inherited/> <!--报表插件的配置--> <configuration/> <!--一组报表的多重规范,每个规范可能有不同的配置。一个规范(报表集)对应一个执行目标。例如,有1,2,3,4,5,6,7,8,9个报表。1,2,5构成A报表集,对应一个执行目标。2,5,8构成B报表集,对应另一个执行目标--> <reportSets> <!--表示报表的一个集合,以及产生该集合的配置--> <reportSet> <!--报表集合的唯一标识符,POM继承时用到,默认值:default --> <id>default<id> <!--产生报表集合时,被使用的报表的配置--> <configuration/> <!--配置是否被继承到子POMs--> <inherited/> <!--这个集合里使用到哪些报表--> <reports/> </reportSet> </reportSets> </plugin> </plugins> </reporting> 项目信息 name <!--项目的名称,Maven产生的文档用--> <name>banseon-maven</name> description <!--项目的详细描述,Maven产生的文档用。当这个元素能够用HTML格式描述时(例如,CDATA中的文本会被解析器忽略,就可以包含HTML标签),不鼓励使用纯文本描述。如果你需要修改产生的web站点的索引页面,你应该修改你自己的索引页文件,而不是调整这里的文档。--> <description>Amavenprojecttostudymaven.</description> url <!--项目主页的URL,Maven产生的文档用--> <url>http://www.baidu.com/banseon</url> inceptionYear <!--项目创建年份,4位数字。当产生版权信息时需要使用这个值。--> <inceptionYear/> licenses <!--该元素描述了项目所有License列表。应该只列出该项目的license列表,不要列出依赖项目的license列表。如果列出多个license,用户可以选择它们中的一个而不是接受所有license。--> <licenses> <!--描述了项目的license,用于生成项目的web站点的license页面,其他一些报表和validation也会用到该元素。--> <license> <!--完整的法律许可的名称。 --> <name>Apache2</name> <!--官方的license正文页面的URL--> <url>http://www.baidu.com/banseon/LICENSE-2.0.txt</url> <!--项目分发的主要方式: repo,可以从Maven库下载 manual,用户必须手动下载和安装依赖--> <distribution>repo</distribution> <!--关于license的补充信息--> <comments>Abusiness-friendlyOSSlicense</comments> </license> </licenses> organization <!--描述项目所属组织的各种属性。Maven产生的文档用--> <organization> <!--组织的全名--> <name>demo</name> <!--组织主页的URL--> <url>http://www.baidu.com/banseon</url> </organization> developers <!--项目开发者列表--> <developers> <!--某个项目开发者的信息--> <developer> <!--SCM里项目开发者的唯一标识符--> <id>HELLOWORLD</id> <!--项目开发者的全名--> <name>banseon</name> <!--项目开发者的email--> <email>banseon@126.com</email> <!--项目开发者的主页的URL--> <url/> <!--项目开发者在项目中扮演的角色,角色元素描述了各种角色--> <roles> <role>ProjectManager</role> <role>Architect</role> </roles> <!--项目开发者所属组织--> <organization>demo</organization> <!--项目开发者所属组织的URL--> <organizationUrl>http://hi.baidu.com/banseon</organizationUrl> <!--项目开发者所在时区,-12到14范围内的整数。--> <timezone>-5</timezone> <!-- 其他配置,键值对 --> <properties> <picUrl>http://tinyurl.com/prv4t</picUrl> </properties> </developer> </developers> contributors <!--项目的其他贡献者列表--> <contributors> <!--项目的其他贡献者。参见developers/developer元素--> <contributor> <name/><email/><url/><organization/><organizationUrl/><roles/><timezone/><properties/> </contributor> </contributors> 环境设置 issueManagement <!--项目的问题管理系统(Bugzilla,Jira,Scarab,或任何你喜欢的问题管理系统)的名称和URL,本例为jira--> <issueManagement> <!--问题管理系统(例如jira)的名字,--> <system>jira</system> <!--该项目使用的问题管理系统的URL--> <url>http://jira.baidu.com/banseon</url> </issueManagement> ciManagement <!--项目持续集成信息--> <ciManagement> <!--持续集成系统的名字,例如continuum--> <system>continuum</system> <!--该项目使用的持续集成系统的URL(如果持续集成系统有web接口的话)。--> <url>http://127.0.0.1:8080/continuum</url> <!--构建完成时,需要通知的开发者/用户的配置项。包括被通知者信息和通知条件(错误,失败,成功,警告)--> <notifiers> <!--配置一种方式,当构建中断时,以该方式通知用户/开发者--> <notifier> <!--传送通知的途径--> <type>mail</type> <!--发生错误时是否通知--> <sendOnError>true</sendOnError> <!--构建失败时是否通知--> <sendOnFailure>true</sendOnFailure> <!--构建成功时是否通知--> <sendOnSuccess>false</sendOnSuccess> <!--发生警告时是否通知--> <sendOnWarning>false</sendOnWarning> <!--弃用。通知发送到哪里--> <address/> <!--通知扩展配置项--> <configuration><address>continuum@127.0.0.1</address></configuration> </notifier> </notifiers> </ciManagement> mailingLists <!--项目相关邮件列表信息--> <mailingLists> <!--该元素描述了项目相关的所有邮件列表。自动产生的网站引用这些信息。--> <mailingList> <!--邮件的名称--> <name>User List</name> <!--发送邮件的地址或链接,如果是邮件地址,创建文档时,mailto:链接会被自动创建--> <post>user@127.0.0.1</post> <!--订阅邮件的地址或链接,如果是邮件地址,创建文档时,mailto:链接会被自动创建--> <subscribe>user-subscribe@127.0.0.1</subscribe> <!--取消订阅邮件的地址或链接,如果是邮件地址,创建文档时,mailto:链接会被自动创建--> <unsubscribe>user-unsubscribe@127.0.0.1</unsubscribe> <!--你可以浏览邮件信息的URL--> <archive>http://127.0.0.1/user/</archive> <!--备用url的链接,可以浏览存档列表。--> <otherArchives> <otherArchive>http://base.google.com/base/1/127.0.0.1</otherArchive> </mailingList> </mailingLists> scm <!--SCM(Source Control Management)标签允许你配置你的代码库,供Maven web站点和其它插件使用。--> <scm> <!--SCM的URL,该URL描述了版本库和如何连接到版本库。欲知详情,请看SCMs提供的URL格式和支持列表。该连接只读。--> <connection>scm:svn:http://127.0.0.1/svn/my-project</connection> <!--给开发者使用的,类似connection元素。即该连接不仅仅只读--> <developerConnection>scm:svn:https://127.0.0.1/svn/my-project</developerConnection> <!--当前代码的标签,在开发阶段默认为HEAD--> <tag>HEAD</tag> <!--指向项目的可浏览SCM库(例如ViewVC或者Fisheye)的URL。--> <url>http://127.0.0.1/websvn/my-project</url> </scm> prerequisites <!--描述了这个项目构建环境中的前提条件。--> <prerequisites> <!--构建该项目或使用该插件所需要的Maven的最低版本。默认值:2.0--> <maven>2.0.6</maven> </prerequisites> repositories <!--远程仓库列表,它是Maven用来填充构建系统本地仓库所使用的一组远程项目。 --> <repositories> <!--包含需要连接到远程仓库的信息 --> <repository> <!--远程仓库唯一标识--> <id>codehausSnapshots</id> <!--远程仓库名称 --> <name>Codehaus Snapshots</name> <!--如何处理远程仓库里发布版本的下载--> <releases> <!--true或者false表示该仓库是否为下载某种类型构件(发布版,快照版)开启。 --> <enabled>false</enabled> <!--该元素指定更新发生的频率。Maven会比较本地POM和远程POM的时间戳。这里的选项是:always(一直),daily(默认,每日),interval:X(这里X是以分钟为单位的时间间隔),或者never(从不)。 --> <updatePolicy>always</updatePolicy> <!--当Maven验证构件校验文件失败时该怎么做-ignore(忽略),fail(失败),或者warn(警告)。--> <checksumPolicy>warn</checksumPolicy> </releases> <!--如何处理远程仓库里快照版本的下载。有了releases和snapshots这两组配置,POM就可以在每个单独的仓库中,为每种类型的构件采取不同的策略。例如,可能有人会决定只为开发目的开启对快照版本下载的支持。参见repositories/repository/releases元素--> <snapshots> <enabled/><updatePolicy/><checksumPolicy/> </snapshots> <!--远程仓库URL,按protocol://hostname/path形式 --> <url>http://snapshots.maven.codehaus.org/maven2</url> <!--用于定位和排序构件的仓库布局类型-可以是default(默认)或者legacy(遗留)。Maven 2为其仓库提供了一个默认的布局;然而,Maven 1.x有一种不同的布局。我们可以使用该元素指定布局是default(默认)还是legacy(遗留)。 --> <layout>default</layout> </repository> </repositories> pluginRepositories <!--包含需要连接到远程插件仓库的信息.参见repositories/repository元素--> <pluginRepositories> <pluginRepository> <releases> <enabled/> <updatePolicy/> <checksumPolicy/> </releases> <snapshots> <enabled/> <updatePolicy/> <checksumPolicy/> </snapshots> <id/> <name/> <url/> <layout/> </pluginRepository> </pluginRepositories> distributionManagement <!--项目分发信息,在执行mvndeploy后表示要发布的位置。有了这些信息就可以把网站部署到远程服务器或者把构件部署到远程仓库。--> <distributionManagement> <!--部署项目产生的构件到远程仓库需要的信息,参见repositories/repository元素--> <repository> <!--true:分配给快照一个唯一的版本号(由时间戳和构建流水号组成)。false:每次都使用相同的版本号 --> <uniqueVersion>true</uniqueVersion> <id/> <name/> <url/> <layout/> <releases> <enabled/> <updatePolicy/> <checksumPolicy/> </releases> <snapshots> <enabled/> <updatePolicy/> <checksumPolicy/> </snapshots> </repository> <!--构件的快照部署到哪里? --> <snapshotRepository> <uniqueVersion>true</uniqueVersion> <id/> <name/> <url/> <layout/> <releases> <enabled/> <updatePolicy/> <checksumPolicy/> </releases> <snapshots> <enabled/> <updatePolicy/> <checksumPolicy/> </snapshots> </snapshotRepository> <!--部署项目的网站需要的信息--> <site> <!--部署位置的唯一标识符,用来匹配站点和settings.xml文件里的配置--> <id>banseon-site</id> <!--部署位置的名称--> <name>businessapiwebsite</name> <!--部署位置的URL,按protocol://hostname/path形式--> <url> scp://svn.baidu.com/banseon:/var/www/localhost/banseon-web </url> </site> <!--项目下载页面的URL。如果没有该元素,用户应该参考主页。使用该元素的原因是:帮助定位那些不在仓库里的构件(由于license限制)。--> <downloadUrl/> <!--如果构件有了新的groupID和artifactID(构件移到了新的位置),这里列出构件的重定位信息。--> <relocation> <!--构件新的groupID--> <groupId/> <!--构件新的artifactID--> <artifactId/> <!--构件新的版本号--> <version/> <!--显示给用户的,关于移动的额外信息,例如原因。--> <message/> </relocation> <!--给出该构件在远程仓库的状态。不得在本地项目中设置该元素,因为这是工具自动更新的。有效的值有:none(默认),converted(仓库管理员从Maven1 POM转换过来),partner(直接从伙伴Maven2仓库同步过来),deployed(从Maven2实例部署),verified(被核实时正确的和最终的)。--> <status/> </distributionManagement> profiles <!--在列的项目构建profile,如果被激活,会修改构建处理--> <profiles> <!--根据环境参数或命令行参数激活某个构建处理--> <profile> <!--构建配置的唯一标识符。即用于命令行激活,也用于在继承时合并具有相同标识符的profile。--> <id>test</id> <!--自动触发profile的条件逻辑。Activation是profile的开启钥匙。如POM中的profile一样,profile的力量来自于它能够在某些特定的环境中自动使用某些特定的值;这些环境通过activation元素指定。activation元素并不是激活profile的唯一方式。settings.xml文件中的activeProfile元素可以包含profile的id。profile也可以通过在命令行,使用-P标记和逗号分隔的列表来显式的激活(如,-P test)。--> <activation> <!--profile默认是否激活的标识--> <activeByDefault>false</activeByDefault> <!--当匹配的jdk被检测到,profile被激活。例如,1.4激活JDK1.4,1.4.0_2,而!1.4激活所有版本不是以1.4开头的JDK。--> <jdk>1.5</jdk> <!--当匹配的操作系统属性被检测到,profile被激活。os元素可以定义一些操作系统相关的属性。--> <os> <!--激活profile的操作系统的名字 --> <name>Windows XP</name> <!--激活profile的操作系统所属家族(如 'windows') --> <family>Windows</family> <!--激活profile的操作系统体系结构 --> <arch>x86</arch> <!--激活profile的操作系统版本--> <version>5.1.2600</version> </os> <!--如果Maven检测到某一个属性(其值可以在POM中通过${name}引用),其拥有对应的name = 值,Profile就会被激活。如果值字段是空的,那么存在属性名称字段就会激活profile,否则按区分大小写方式匹配属性值字段--> <property> <!--激活profile的属性的名称--> <name>mavenVersion</name> <!--激活profile的属性的值 --> <value>2.0.3</value> </property> <!--提供一个文件名,通过检测该文件的存在或不存在来激活profile。missing检查文件是否存在,如果不存在则激活profile。另一方面,exists则会检查文件是否存在,如果存在则激活profile。--> <file> <!--如果指定的文件存在,则激活profile。 --> <exists>${basedir}/file2.properties</exists> <!--如果指定的文件不存在,则激活profile。--> <missing>${basedir}/file1.properties</missing> </file> </activation> <!--构建项目所需要的信息。参见build元素--> <build> <defaultGoal/> <resources> <resource> <targetPath/><filtering/><directory/><includes/><excludes/> </resource> </resources> <testResources> <testResource> <targetPath/><filtering/><directory/><includes/><excludes/> </testResource> </testResources> <directory/><finalName/><filters/> <pluginManagement> <plugins> <!--参见build/pluginManagement/plugins/plugin元素--> <plugin> <groupId/><artifactId/><version/><extensions/> <executions> <execution> <id/><phase/><goals/><inherited/><configuration/> </execution> </executions> <dependencies> <!--参见dependencies/dependency元素--> <dependency> ...... </dependency> </dependencies> <goals/><inherited/><configuration/> </plugin> </plugins> </pluginManagement> <plugins> <!--参见build/pluginManagement/plugins/plugin元素--> <plugin> <groupId/><artifactId/><version/><extensions/> <executions> <execution> <id/><phase/><goals/><inherited/><configuration/> </execution> </executions> <dependencies> <!--参见dependencies/dependency元素--> <dependency> ...... </dependency> </dependencies> <goals/><inherited/><configuration/> </plugin> </plugins> </build> <!--发现依赖和扩展的远程仓库列表。--> <repositories> <!--参见repositories/repository元素--> <repository> <releases> <enabled/><updatePolicy/><checksumPolicy/> </releases> <snapshots> <enabled/><updatePolicy/><checksumPolicy/> </snapshots> <id/><name/><url/><layout/> </repository> </repositories> <!--该元素描述了项目相关的所有依赖。这些依赖组成了项目构建过程中的一个个环节。它们自动从项目定义的仓库中下载。要获取更多信息,请看项目依赖机制。--> <dependencies> <!--参见dependencies/dependency元素--> <dependency> ...... </dependency> </dependencies> <!--不赞成使用.现在Maven忽略该元素.--> <reports/> <!--参见distributionManagement元素--> <distributionManagement> ...... </distributionManagement> <!--参见properties元素--> <properties/> </profile> </profiles> </project> <!--参考: http://maven.apache.org/ref/3.1.0/maven-model/maven.html https://maven.apache.org/pom.html --> 注:转载需注明出处及作者。 流柯
Maven使用中央仓库的同时,使用lib下的包 pom.xml添加如下配置 <build> <plugins> <plugin> <artifactId>maven-compiler-plugin</artifactId> <configuration> <compilerArguments> <extdirs>src\main\webapp\WEB-INF\lib</extdirs> </compilerArguments> </configuration> </plugin> </plugins> </build> 注:转载需注明出处及作者。 流柯
在pom.xml添加如下配置即可 <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> </properties> 注:转载需注明出处及作者。 流柯
方法仅作参考: 1.修改HTTP请求下面的Impementation选项,改成HttpClient4 2.在user.properties文件内修改: hc.parameters.file=hc.parameters #Jmeter 2.10以后禁用了失败请求重试 3.在hc.parameters文件内修改: http.connection.stalecheck$Boolean=true #Jmeter 2.10以后禁用了失效检查 重启Jmeter再尝试一下 注:转载需注明出处及作者。 流柯
基本格式 : * * * * * command 分 时 日 月 周 命令 第1列表示分钟1~59 每分钟用*或者 */1表示 第2列表示小时1~23(0表示0点) 第3列表示日期1~31 第4列表示月份1~12 第5列标识号星期0~6(0表示星期天) 第6列要运行的命令 crontab文件的一些例子: 30 21 * * * /usr/local/etc/rc.d/lighttpd restart 上面的例子表示每晚的21:30重启apache。 45 4 1,10,22 * * /usr/local/etc/rc.d/lighttpd restart 上面的例子表示每月1、10、22日的4 : 45重启apache。 10 1 * * 6,0 /usr/local/etc/rc.d/lighttpd restart 上面的例子表示每周六、周日的1 : 10重启apache。 0,30 18-23 * * * /usr/local/etc/rc.d/lighttpd restart 上面的例子表示在每天18 : 00至23 : 00之间每隔30分钟重启apache。 0 23 * * 6 /usr/local/etc/rc.d/lighttpd restart 上面的例子表示每星期六的11 : 00 pm重启apache。 * */1 * * * /usr/local/etc/rc.d/lighttpd restart 每一小时重启apache * 23-7/1 * * * /usr/local/etc/rc.d/lighttpd restart 晚上11点到早上7点之间,每隔一小时重启apache 0 11 4 * mon-wed /usr/local/etc/rc.d/lighttpd restart 每月的4号与每周一到周三的11点重启apache 0 4 1 jan * /usr/local/etc/rc.d/lighttpd restart 一月一号的4点重启apache 名称 : crontab 使用权限 : 所有使用者 使用方式 : crontab file [-u user]-用指定的文件替代目前的crontab。 crontab-[-u user]-用标准输入替代目前的crontab. crontab-1[user]-列出用户目前的crontab. crontab-e[user]-编辑用户目前的crontab. crontab-d[user]-删除用户目前的crontab. crontab-c dir- 指定crontab的目录。 crontab文件的格式:M H D m d cmd. M: 分钟(0-59)。 H:小时(0-23)。 D:天(1-31)。 m: 月(1-12)。 d: 一星期内的天(0~6,0为星期天)。 cmd要运行的程序,程序被送入sh执行,这个shell只有USER,HOME,SHELL这三个环境变量 说明 : crontab 是用来让使用者在固定时间或固定间隔执行程序之用,换句话说,也就是类似使用者的时程表。-u user 是指设定指定 user 的时程表,这个前提是你必须要有其权限(比如说是 root)才能够指定他人的时程表。如果不使用 -u user 的话,就是表示设 定自己的时程表。 参数 : crontab -e : 执行文字编辑器来设定时程表,内定的文字编辑器是 VI,如果你想用别的文字编辑器,则请先设定 VISUAL 环境变数 来指定使用那个文字编辑器(比如说 setenv VISUAL joe) crontab -r : 删除目前的时程表 crontab -l : 列出目前的时程表 crontab file [-u user]-用指定的文件替代目前的crontab。 时程表的格式如下 : f1 f2 f3 f4 f5 program 其中 f1 是表示分钟,f2 表示小时,f3 表示一个月份中的第几日,f4 表示月份,f5 表示一个星期中的第几天。program 表示要执 行的程序。 当 f1 为 * 时表示每分钟都要执行 program,f2 为 * 时表示每小时都要执行程序,其馀类推 当 f1 为 a-b 时表示从第 a 分钟到第 b 分钟这段时间内要执行,f2 为 a-b 时表示从第 a 到第 b 小时都要执行,其馀类推 当 f1 为 */n 时表示每 n 分钟个时间间隔执行一次,f2 为 */n 表示每 n 小时个时间间隔执行一次,其馀类推当 f1 为 a, b, c,... 时表示第 a, b, c,... 分钟要执行,f2 为 a, b, c,... 时表示第 a, b, c...个小时要执行,其馀类推 使用者也可以将所有的设定先存放在档案 file 中,用 crontab file 的方式来设定时程表。 例子 : #每天早上7点执行一次 /bin/ls : 0 7 * * * /bin/ls 在 12 月内, 每天的早上 6 点到 12 点中,每隔3个小时执行一次 /usr/bin/backup : 0 6-12/3 * 12 * /usr/bin/backup 周一到周五每天下午 5:00 寄一封信给 alex@domain.name : 0 17 * * 1-5 mail -s "hi" alex@domain.name < /tmp/maildata 每月每天的午夜 0 点 20 分, 2 点 20 分, 4 点 20 分....执行 echo "haha" 20 0-23/2 * * * echo "haha" 注意 : 当程序在你所指定的时间执行后,系统会寄一封信给你,显示该程序执行的内容,若是你不希望收到这样的信,请在每一行空一格之 后加上 > /dev/null 2>&1 即可 例子2 : #每天早上6点10分 10 6 * * * date #每两个小时 0 */2 * * * date #晚上11点到早上8点之间每两个小时,早上8点 0 23-7/2,8 * * * date #每个月的4号和每个礼拜的礼拜一到礼拜三的早上11点 0 11 4 * mon-wed date #1月份日早上4点 0 4 1 jan * date 范例 $crontab -l 列出用户目前的crontab. 注:转载需注明出处及作者。 流柯
有同学遇到这种情况,jmeter请求一个网站,各项参数填写正确,可是响应是403,同样的请求放在浏览器执行就没有问题; 这是因为被请求的网站做了请求来源过滤,来源不明的请求拒绝访问,我们需要在jmeter中添加模拟浏览器信息。 举个栗子,CSDN博客(blog.csdn.net)就有这样的机制。 用jmeter请求blog.csdn.net 响应返回403,同样的请求放在浏览器中没有问题。 用浏览器开发者工具抓一下浏览器的请求 可以看出,请求的header中,User-Agent是不同的 好 ,我们在jmeter中添加header的User-Agent信息,模拟浏览器请求看一下 可以看到,已经成功请求并正确响应,解决问题。 注:转载需注明出处及作者。 流柯
在使用tomcat时,若要使用管理监控功能,需要用用户名密码登录使用,而tomcat7默认是将用户是注释的,所以需要配置后使用, 配置文件为根目录下的/conf/tomcat-users.xml文件。 看一下官方说明: 可以看出,tomcat7较之前有了变化,权限分为4种 manager-guimanager-scriptmanager-jmxmanager-status 而且manger-gui不能同时与manger-script或manger-jmx同时使用 所以 我们可以配置如下: <tomcat-users> <role rolename="admin"/> <role rolename="admin-gui"/> <role rolename="manager"/> <role rolename="manager-gui"/> <role rolename="manager-script"/> <role rolename="manager-jmx"/> <role rolename="manager-status"/> <user username="admin" password="admin" roles="admin-gui,manager-gui"/> <user username="liuke" password="liuke" roles="manager-script"/> <user username="lk" password="lk" roles="manager-jmx"/> </tomcat-users> 重启Tomcat生效。 输入相应用户名密码即可使用Server Status、Manager App、host-manager功能。 注:转载需注明出处及作者。 流柯
本文使用的tomcat版本为7.0.77。 要通过JMX远程监控Tomcat,首先需要进行Tomcat的JMX远程配置。 注意:此配置添加在catalina.bat文件开头的注释行(rem或#)后面即可。 不需鉴权的配置: 先修改Tomcat的启动脚本,windows下为bin/catalina.bat(linux下为catalina.sh),添加以下内容: set JMX_REMOTE_CONFIG=-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=8999 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false set CATALINA_OPTS=%CATALINA_OPTS% %JMX_REMOTE_CONFIG% linux为 JAVA_OPTS=-Dcom.sun.management.jmxremote.port=8999 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.port=8999,是jmxremote使用的端口号,可修改。 -Dcom.sun.management.jmxremote.authenticate=false,表示不需要鉴权,主机+端口号即可监控。 需要鉴权的配置: set JMX_REMOTE_CONFIG=-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=8999 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=true -Dcom.sun.management.jmxremote.password.file=../conf/jmxremote.password -Dcom.sun.management.jmxremote.access.file=../conf/jmxremote.access set CATALINA_OPTS=%CATALINA_OPTS% %JMX_REMOTE_CONFIG% 复制并修改授权文件 JAVA_HOME/jre/lib/management下有jmxremote.access和jmxremote.password.template的模板文件,将两个文件复制到CATALINA_BASE/conf目录下*重命名jmxremote.password.template文件为jmxremote.password *修改CATALINA_BASE/conf/jmxremote.access 添加内容: monitorRole readonly controlRole readwrite*修改CATALINA_BASE/conf/jmxremote.password 添加内容: monitorRole liuke #可自定义 controlRole liuke #可自定义 使用jconsole或jvisualvm测试JMX 运行JAVA_HOME/bin目录下的jconsole或jvisualvm,打开控制台,然后建立连接,填写地址、端口号、用户名、口令即可连接。 注:转载需注明出处及作者。 流柯
报错如下: # pip Traceback (most recent call last): File "/usr/bin/pip", line 5, in <module> from pkg_resources import load_entry_point ImportError: No module named pkg_resources 出现这个问题是因为:虽然已经把Python升级到了2.7版本,但是pip仍然是原来的版本,仍在原来python的site-package里面 CentOS6.8环境下,默认是python2.6.6,site-package在 # /usr/lib/python2.6/site-packages/ 很多模块都被安装在这里。直接输入pip,还是使用的原来的pip。所以我们的思路是:应该在新的Python中安装pip,这样才不会报错。 遇到此问题的人很多,网上博客都是互相抄,没有真正解决问题的。有一国外网站给出了解决方案: # wget https://pypi.python.org/packages/source/s/setuptools/setuptools-3.5.1.zip # unzip setuptools-3.5.1.zip # /usr/local/bin/pyton2.7 distribute_setup.py 使用新版本的python来运行这个脚本,这个会自动安装出来一个easy_install,然后使用这个新的easy_install来安装pip就可以了! # /usr/local/bin/easy_install pip # /usr/local/bin/pip -V pip 9.0.1 from /usr/local/lib/python2.7/site-packages/pip-9.0.1-py2.7.egg (python 2.7) 安装生成的所有二进制文件,都是在你的PYTHON_HOME/bin/,因为我的是安装在/usr/local/python/,所以命令都在这里,以后再调用pip要使用绝对路径,或者做链接! 2.7的模块是在以下目录 # /usr/local/lib/python2.7/site-packages 附:脚本的原文 #!python """Bootstrap distribute installation If you want to use setuptools in your package's setup.py, just include this file in the same directory with it, and add this to the top of your setup.py:: from distribute_setup import use_setuptools use_setuptools() If you want to require a specific version of setuptools, set a download mirror, or use an alternate download directory, you can do so by supplying the appropriate options to ``use_setuptools()``. This file can also be run as a script to install or upgrade setuptools. """ import os import shutil import sys import time import fnmatch import tempfile import tarfile import optparse from distutils import log try: from site import USER_SITE except ImportError: USER_SITE = None try: import subprocess def _python_cmd(*args): args = (sys.executable,) + args return subprocess.call(args) == 0 except ImportError: # will be used for python 2.3 def _python_cmd(*args): args = (sys.executable,) + args # quoting arguments if windows if sys.platform == 'win32': def quote(arg): if ' ' in arg: return '"%s"' % arg return arg args = [quote(arg) for arg in args] return os.spawnl(os.P_WAIT, sys.executable, *args) == 0 DEFAULT_VERSION = "0.6.49" DEFAULT_URL = "http://pypi.python.org/packages/source/d/distribute/" SETUPTOOLS_FAKED_VERSION = "0.6c11" SETUPTOOLS_PKG_INFO = """\ Metadata-Version: 1.0 Name: setuptools Version: %s Summary: xxxx Home-page: xxx Author: xxx Author-email: xxx License: xxx Description: xxx """ % SETUPTOOLS_FAKED_VERSION def _install(tarball, install_args=()): # extracting the tarball tmpdir = tempfile.mkdtemp() log.warn('Extracting in %s', tmpdir) old_wd = os.getcwd() try: os.chdir(tmpdir) tar = tarfile.open(tarball) _extractall(tar) tar.close() # going in the directory subdir = os.path.join(tmpdir, os.listdir(tmpdir)[0]) os.chdir(subdir) log.warn('Now working in %s', subdir) # installing log.warn('Installing Distribute') if not _python_cmd('setup.py', 'install', *install_args): log.warn('Something went wrong during the installation.') log.warn('See the error message above.') # exitcode will be 2 return 2 finally: os.chdir(old_wd) shutil.rmtree(tmpdir) def _build_egg(egg, tarball, to_dir): # extracting the tarball tmpdir = tempfile.mkdtemp() log.warn('Extracting in %s', tmpdir) old_wd = os.getcwd() try: os.chdir(tmpdir) tar = tarfile.open(tarball) _extractall(tar) tar.close() # going in the directory subdir = os.path.join(tmpdir, os.listdir(tmpdir)[0]) os.chdir(subdir) log.warn('Now working in %s', subdir) # building an egg log.warn('Building a Distribute egg in %s', to_dir) _python_cmd('setup.py', '-q', 'bdist_egg', '--dist-dir', to_dir) finally: os.chdir(old_wd) shutil.rmtree(tmpdir) # returning the result log.warn(egg) if not os.path.exists(egg): raise IOError('Could not build the egg.') def _do_download(version, download_base, to_dir, download_delay): egg = os.path.join(to_dir, 'distribute-%s-py%d.%d.egg' % (version, sys.version_info[0], sys.version_info[1])) if not os.path.exists(egg): tarball = download_setuptools(version, download_base, to_dir, download_delay) _build_egg(egg, tarball, to_dir) sys.path.insert(0, egg) import setuptools setuptools.bootstrap_install_from = egg def use_setuptools(version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir, download_delay=15, no_fake=True): # making sure we use the absolute path to_dir = os.path.abspath(to_dir) was_imported = 'pkg_resources' in sys.modules or \ 'setuptools' in sys.modules try: try: import pkg_resources # Setuptools 0.7b and later is a suitable (and preferable) # substitute for any Distribute version. try: pkg_resources.require("setuptools>=0.7b") return except (pkg_resources.DistributionNotFound, pkg_resources.VersionConflict): pass if not hasattr(pkg_resources, '_distribute'): if not no_fake: _fake_setuptools() raise ImportError except ImportError: return _do_download(version, download_base, to_dir, download_delay) try: pkg_resources.require("distribute>=" + version) return except pkg_resources.VersionConflict: e = sys.exc_info()[1] if was_imported: sys.stderr.write( "The required version of distribute (>=%s) is not available,\n" "and can't be installed while this script is running. Please\n" "install a more recent version first, using\n" "'easy_install -U distribute'." "\n\n(Currently using %r)\n" % (version, e.args[0])) sys.exit(2) else: del pkg_resources, sys.modules['pkg_resources'] # reload ok return _do_download(version, download_base, to_dir, download_delay) except pkg_resources.DistributionNotFound: return _do_download(version, download_base, to_dir, download_delay) finally: if not no_fake: _create_fake_setuptools_pkg_info(to_dir) def download_setuptools(version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir, delay=15): """Download distribute from a specified location and return its filename `version` should be a valid distribute version number that is available as an egg for download under the `download_base` URL (which should end with a '/'). `to_dir` is the directory where the egg will be downloaded. `delay` is the number of seconds to pause before an actual download attempt. """ # making sure we use the absolute path to_dir = os.path.abspath(to_dir) try: from urllib.request import urlopen except ImportError: from urllib2 import urlopen tgz_name = "distribute-%s.tar.gz" % version url = download_base + tgz_name saveto = os.path.join(to_dir, tgz_name) src = dst = None if not os.path.exists(saveto): # Avoid repeated downloads try: log.warn("Downloading %s", url) src = urlopen(url) # Read/write all in one block, so we don't create a corrupt file # if the download is interrupted. data = src.read() dst = open(saveto, "wb") dst.write(data) finally: if src: src.close() if dst: dst.close() return os.path.realpath(saveto) def _no_sandbox(function): def __no_sandbox(*args, **kw): try: from setuptools.sandbox import DirectorySandbox if not hasattr(DirectorySandbox, '_old'): def violation(*args): pass DirectorySandbox._old = DirectorySandbox._violation DirectorySandbox._violation = violation patched = True else: patched = False except ImportError: patched = False try: return function(*args, **kw) finally: if patched: DirectorySandbox._violation = DirectorySandbox._old del DirectorySandbox._old return __no_sandbox def _patch_file(path, content): """Will backup the file then patch it""" f = open(path) existing_content = f.read() f.close() if existing_content == content: # already patched log.warn('Already patched.') return False log.warn('Patching...') _rename_path(path) f = open(path, 'w') try: f.write(content) finally: f.close() return True _patch_file = _no_sandbox(_patch_file) def _same_content(path, content): f = open(path) existing_content = f.read() f.close() return existing_content == content def _rename_path(path): new_name = path + '.OLD.%s' % time.time() log.warn('Renaming %s to %s', path, new_name) os.rename(path, new_name) return new_name def _remove_flat_installation(placeholder): if not os.path.isdir(placeholder): log.warn('Unkown installation at %s', placeholder) return False found = False for file in os.listdir(placeholder): if fnmatch.fnmatch(file, 'setuptools*.egg-info'): found = True break if not found: log.warn('Could not locate setuptools*.egg-info') return log.warn('Moving elements out of the way...') pkg_info = os.path.join(placeholder, file) if os.path.isdir(pkg_info): patched = _patch_egg_dir(pkg_info) else: patched = _patch_file(pkg_info, SETUPTOOLS_PKG_INFO) if not patched: log.warn('%s already patched.', pkg_info) return False # now let's move the files out of the way for element in ('setuptools', 'pkg_resources.py', 'site.py'): element = os.path.join(placeholder, element) if os.path.exists(element): _rename_path(element) else: log.warn('Could not find the %s element of the ' 'Setuptools distribution', element) return True _remove_flat_installation = _no_sandbox(_remove_flat_installation) def _after_install(dist): log.warn('After install bootstrap.') placeholder = dist.get_command_obj('install').install_purelib _create_fake_setuptools_pkg_info(placeholder) def _create_fake_setuptools_pkg_info(placeholder): if not placeholder or not os.path.exists(placeholder): log.warn('Could not find the install location') return pyver = '%s.%s' % (sys.version_info[0], sys.version_info[1]) setuptools_file = 'setuptools-%s-py%s.egg-info' % \ (SETUPTOOLS_FAKED_VERSION, pyver) pkg_info = os.path.join(placeholder, setuptools_file) if os.path.exists(pkg_info): log.warn('%s already exists', pkg_info) return log.warn('Creating %s', pkg_info) try: f = open(pkg_info, 'w') except EnvironmentError: log.warn("Don't have permissions to write %s, skipping", pkg_info) return try: f.write(SETUPTOOLS_PKG_INFO) finally: f.close() pth_file = os.path.join(placeholder, 'setuptools.pth') log.warn('Creating %s', pth_file) f = open(pth_file, 'w') try: f.write(os.path.join(os.curdir, setuptools_file)) finally: f.close() _create_fake_setuptools_pkg_info = _no_sandbox( _create_fake_setuptools_pkg_info ) def _patch_egg_dir(path): # let's check if it's already patched pkg_info = os.path.join(path, 'EGG-INFO', 'PKG-INFO') if os.path.exists(pkg_info): if _same_content(pkg_info, SETUPTOOLS_PKG_INFO): log.warn('%s already patched.', pkg_info) return False _rename_path(path) os.mkdir(path) os.mkdir(os.path.join(path, 'EGG-INFO')) pkg_info = os.path.join(path, 'EGG-INFO', 'PKG-INFO') f = open(pkg_info, 'w') try: f.write(SETUPTOOLS_PKG_INFO) finally: f.close() return True _patch_egg_dir = _no_sandbox(_patch_egg_dir) def _before_install(): log.warn('Before install bootstrap.') _fake_setuptools() def _under_prefix(location): if 'install' not in sys.argv: return True args = sys.argv[sys.argv.index('install') + 1:] for index, arg in enumerate(args): for option in ('--root', '--prefix'): if arg.startswith('%s=' % option): top_dir = arg.split('root=')[-1] return location.startswith(top_dir) elif arg == option: if len(args) > index: top_dir = args[index + 1] return location.startswith(top_dir) if arg == '--user' and USER_SITE is not None: return location.startswith(USER_SITE) return True def _fake_setuptools(): log.warn('Scanning installed packages') try: import pkg_resources except ImportError: # we're cool log.warn('Setuptools or Distribute does not seem to be installed.') return ws = pkg_resources.working_set try: setuptools_dist = ws.find( pkg_resources.Requirement.parse('setuptools', replacement=False) ) except TypeError: # old distribute API setuptools_dist = ws.find( pkg_resources.Requirement.parse('setuptools') ) if setuptools_dist is None: log.warn('No setuptools distribution found') return # detecting if it was already faked setuptools_location = setuptools_dist.location log.warn('Setuptools installation detected at %s', setuptools_location) # if --root or --preix was provided, and if # setuptools is not located in them, we don't patch it if not _under_prefix(setuptools_location): log.warn('Not patching, --root or --prefix is installing Distribute' ' in another location') return # let's see if its an egg if not setuptools_location.endswith('.egg'): log.warn('Non-egg installation') res = _remove_flat_installation(setuptools_location) if not res: return else: log.warn('Egg installation') pkg_info = os.path.join(setuptools_location, 'EGG-INFO', 'PKG-INFO') if (os.path.exists(pkg_info) and _same_content(pkg_info, SETUPTOOLS_PKG_INFO)): log.warn('Already patched.') return log.warn('Patching...') # let's create a fake egg replacing setuptools one res = _patch_egg_dir(setuptools_location) if not res: return log.warn('Patching complete.') _relaunch() def _relaunch(): log.warn('Relaunching...') # we have to relaunch the process # pip marker to avoid a relaunch bug _cmd1 = ['-c', 'install', '--single-version-externally-managed'] _cmd2 = ['-c', 'install', '--record'] if sys.argv[:3] == _cmd1 or sys.argv[:3] == _cmd2: sys.argv[0] = 'setup.py' args = [sys.executable] + sys.argv sys.exit(subprocess.call(args)) def _extractall(self, path=".", members=None): """Extract all members from the archive to the current working directory and set owner, modification time and permissions on directories afterwards. `path' specifies a different directory to extract to. `members' is optional and must be a subset of the list returned by getmembers(). """ import copy import operator from tarfile import ExtractError directories = [] if members is None: members = self for tarinfo in members: if tarinfo.isdir(): # Extract directories with a safe mode. directories.append(tarinfo) tarinfo = copy.copy(tarinfo) tarinfo.mode = 448 # decimal for oct 0700 self.extract(tarinfo, path) # Reverse sort directories. if sys.version_info < (2, 4): def sorter(dir1, dir2): return cmp(dir1.name, dir2.name) directories.sort(sorter) directories.reverse() else: directories.sort(key=operator.attrgetter('name'), reverse=True) # Set correct owner, mtime and filemode on directories. for tarinfo in directories: dirpath = os.path.join(path, tarinfo.name) try: self.chown(tarinfo, dirpath) self.utime(tarinfo, dirpath) self.chmod(tarinfo, dirpath) except ExtractError: e = sys.exc_info()[1] if self.errorlevel > 1: raise else: self._dbg(1, "tarfile: %s" % e) def _build_install_args(options): """ Build the arguments to 'python setup.py install' on the distribute package """ install_args = [] if options.user_install: if sys.version_info < (2, 6): log.warn("--user requires Python 2.6 or later") raise SystemExit(1) install_args.append('--user') return install_args def _parse_args(): """ Parse the command line for options """ parser = optparse.OptionParser() parser.add_option( '--user', dest='user_install', action='store_true', default=False, help='install in user site package (requires Python 2.6 or later)') parser.add_option( '--download-base', dest='download_base', metavar="URL", default=DEFAULT_URL, help='alternative URL from where to download the distribute package') options, args = parser.parse_args() # positional arguments are ignored return options def main(version=DEFAULT_VERSION): """Install or upgrade setuptools and EasyInstall""" options = _parse_args() tarball = download_setuptools(download_base=options.download_base) return _install(tarball, _build_install_args(options)) if __name__ == '__main__': sys.exit(main()) 此文在作者原文基础上修改整理而成。 注:转载需注明出处及作者。 流柯
pydev for eclipse 旧版:https://dl.bintray.com/fabioz/pydev/old/ http://www.pydev.org/update_sites/4.5.5/ 新版:http://pydev.org/updates eclipse国内镜像站 北京理工大学 http://mirror.bit.edu.cn/eclipse/ 中国科学技术大学 http://mirrors.ustc.edu.cn/eclipse/ 大连东软信息学院 http://mirrors.neusoft.edu.cn/eclipse/ http://mirror.bit.edu.cn/eclipse/technology/epp/downloads/release/juno/SR1/eclipse-jee-juno-SR1-win32.zip eclipse语言包: http://www.eclipse.org/babel/downloads.php http://download.eclipse.org/technology/babel/babel_language_packs/R0.14.1/mars/mars.php http://archive.eclipse.org/technology/babel/update-site/R0.13.1/kepler 在线配置:http://download.eclipse.org/technology/babel/update-site/R0.14.1/mars http://eclipse-color-theme.github.com/update https://visualvm.github.io/archive/uc/release136/updates.xml.gz 注:转载需注明出处及作者。 流柯
jmeter时间格式化 #17位时间取到毫秒 ${__time(yyyyMMdd-HHmmssSSS,)} #10位时间戳 ${__time(/1000,)} yyyyMMddHHmmss yyyy年、 MM月、 dd日、 HH时、 mm分、 ss秒。 ${__time(yyyy/MM/dd HH:mm:ss,date)} 以上函数输出为2017/06/14 10:36:08 完毕。 注:转载需注明出处及作者。 流柯
在测试过程中,有时候需要jmeter跨线程组传值,jmeter本身又不具备此功能,那么,又该如何实现呢? 其实,我们可以通过BeanShell去实现。 实现过程如下: 1.线程组A中,使用正则表达式提取器提取需要传递的值,并保存为变量,如blog 2.使用BeanShell PostProcessor获取blog并赋值给nblog 3.在线程组B中,使用以下方法引用 ${__P(nblog,)} 即可。 详细过程截图如下: OK。 注:转载需注明出处及作者。 流柯
表字段分析 关键指标类型 关键指标名称 关键指标含义 SYS_SUMM CPU% cpu占有率变化情况; IO/sec IO的变化情况; AAA AIX AIX版本号; cpus CPU数量; hardware 被测主机处理器技术; host 被测主机名; interval 监控取样间隔;(秒) kernel 被测主机内核信息; CPU_ALL User% 显示在用户模式下执行的程序所使用的 CPU 百分比; Sys% 显示在内核模式下执行的程序所使用的 CPU 百分比; Wait% 显示等待 IO 所花的时间百分比; Idle% 显示 CPU 的空闲时间百分比; CPU% CPU总体占用情况; DISKBUSY Disk %Busy Hostname 执行间隔时间列表; hdisknn 每个磁盘执行采样数据;(磁盘设备的占用百分比) DISK_SUMM Disk total kb/s Hostname 执行间隔时间列表; Disk Read kb/s 每个磁盘执行采样数据;(磁盘设备的读速率) Disk Write kb/s 每个磁盘执行采样数据;(磁盘设备的写速率) IO/sec 每秒钟输出到物理磁盘的传输次数; NET read/write 本sheet显示系统中每个网络适配器的数据传输速率(千字节/秒) JFSFILE JFS Filespace %Used Hostname 执行间隔时间列表; file system/LV 文件系统以及mount磁盘设备已使用空间百分比; JFSINODE JFS Inode %Used Hostname 执行间隔时间列表; file system/LV 文件系统以及mount磁盘设备的inode已使用空间百分比; MEM Memory Hostname 执行间隔时间列表; Real Free % 实际剩余内存百分比; Virtual free % 虚拟剩余内存百分比; Real free(MB) 实际剩余内存大小;(MB) Virtual free(MB) 虚拟剩余内存大小;(MB) Real total(MB) 实际内存总体大小;(MB) Virtual total(MB) 虚拟内存总体大小;(MB) PAGE faults 每秒的page faults(页错误)数; pgin 每秒钟所读入的页数,包括从文件系统读取的页数 pgout 每秒钟所写出的页数,包括写到文件系统的页数 pgsin 每秒钟从页面空间所读取的页数 pgsout 每秒钟写到页面空间的页数 reclaims 从nmon回收这项之前的10个,和vmstat报告的值是一样的,代表了页替换机制释放的pages/sec的数量 scans 扫描页替换机制的pages/sec的数量,和vmstat报告的值是一样的,页替换在空闲页数量到达最小值时初始化,在空闲到达最大值时停止 cycles 周期 times/sec的数值,页替换机制需要扫描整个页表,来补充空闲列表。这和vmstat报告的cy数值一样,只是vmstat报告的这个值是整形值,而nmon报告的是实型值 fsin 分析器计算的数据为pgin-pgsin的图形处理所用 fsout 分析器计算的数据为pgout-pgsout的图形处理所用 sr/fr 分析器计算的数据为scans/reclaims的图形处理所用 命令的操作 nmon 命令 用途 以交互方式显示本地系统统计信息并以记录方式记录系统统计信息。 语法 交互方式: nmon [ -h ] nmon [ -s < seconds > ] [ -c < count > ] [ -b ] [ -B ] [ -g < filename > ] [ -k disklist ] [ -C < process1:process2:..:processN > ] 记录方式: nmon [ -f | -F filename | -x | -X | -z ] [ -r <<A href="http://publib.boulder.ibm.com/infocenter/aix/v6r1/topic/com.ibm.aix.cmds/doc/aixcmds4/nmon.htm#nmp-r"> runname > ] [ -t | -T | -Y ] [ -s seconds ] [ -c number ] [ -w number ] [ -l dpl ] [ -d ] [ -g filename ] [ -k disklist ] [ -C ] [ -G ] [ -K ] [ -o outputpath ] [ -D ] [ -E ] [ -J ] [ -V ] [ -P ] [ -M ] [ -N ] [ -W ] [ -S ] [ -^ ] [ -O ] [ -L ] [ -I percent ] [ -A ] [ -m <<A href="http://publib.boulder.ibm.com/infocenter/aix/v6r1/topic/com.ibm.aix.cmds/doc/aixcmds4/nmon.htm#nmp-di"> dir > ] [ -Z priority ] 注: 在记录方式下,仅指定 -f、-F、-z、-x 或 -X 标志的其中之一作为第一个参数。 描述 nmon 命令显示和记录本地系统信息。此命令可以采用交互方式或记录方式运行。如果指定 -F、-f、-X、-x 和 -Z 标志中的任何一个,那么 nmon 命令处于记录方式。否则 nmon 命令处于交互方式。 nmon 命令以交互方式提供下列视图: 系统资源视图(使用 r 键) 进程视图(使用 t 和 u 键) AIO 进程视图(使用 A 键) 处理器使用情况小视图(使用 c 键) 处理器使用情况大视图(使用 C 键) 共享处理器逻辑分区视图(使用 p 键) NFS 面板(使用 N 键) 网络接口视图(使用 n 键) WLM 视图(使用 W 键) 磁盘繁忙情况图(使用 o 键) 磁盘组(使用 g 键) ESS 虚拟路径统计信息视图(使用 e 键) JFS 视图(使用 j 键) 内核统计信息(使用 k 键) 长期处理器平均使用率视图(使用 l 键) 大页分析(使用 L 键) 调页空间(使用 P 键) 卷组统计信息(使用 V 键) 磁盘统计信息(使用 D 键) 磁盘统计信息及图形(使用 d 键) 内存和调页统计信息(使用 m 键) 适配器 I/O 统计信息(使用 a 键) 共享以太网适配器统计信息(使用 O 键) 冗余检查良好/警告/危险视图(使用 v 键) 详细信息页统计信息(使用 M 键) 光纤通道适配器统计信息(使用 ^ 键) 在记录方式下,此命令会生成 .nmon 文件。可以通过打开这些文件来直接进行查看,也可以使用后处理工具(例如,nmon 分析器)来查看。在记录期间,nmon 工具会与 shell 断开连接,以确保该命令即使在您注销的情况下仍然继续运行。 如果每次启动 nmon 命令时使用同一组键,那么可将这些键放在 NMON shell 变量中。例如,可运行以下命令: export NMON=mcd 然后运行 nmon 命令。 要从命令行停止 nmon 命令,请将 kill -USR2 与 nmon 进程标识配合使用。 要显示 nmon 记录的后台进程标识,请将 nmon 命令与 -p 标志配合使用。 要限制 nmon 命令列示的进程(联机或至文件),可在从 NMONCMD0 至 NMONCMD63 的环境变量中设置程序名称,或将 -C 标志与 cmd:cmd:cmd 参数配合使用。例如,可输入以下命令: nmon -C ksh:vi:syncd 要将 nmon 列示的磁盘限制为最多 64 个磁盘(仅限于联机磁盘),请将 -k 标志与 diskname 参数配合使用。例如,可输入以下命令: nmon -k hdisk2,hdisk0,hdisk3 在记录期间,nmon 工具会与 shell 断开连接,以确保该命令即使在您注销的情况下仍然继续运行。如果使用“随需应变”记录设施触发了记录,情况并非如此。 在 nmon 中记录或监视日志文件系统(JFS)统计信息可避免卸载文件系统,原因是收集统计信息时该文件系统在使用中。 在工作负载分区(WPAR)中,nmon 命令会显示处理器和内存统计信息的全局值。余下值是特定于WPAR的。不能在WPAR中检索以下统计信息,并且 nmon 屏幕不支持它们出现在WPAR中: 磁盘、磁盘 I/O 图、磁盘繁忙情况图、磁盘组 磁盘适配器 调页空间 卷组 ESS/虚拟路径 光纤通道适配器 VIOS 共享以太网适配器 处于交互方式的标志 可在交互方式下使用下列标志。 -s < seconds > 刷新屏幕之间的时间间隔。缺省值为 2 秒。 -c < count > 必须刷新屏幕的次数。 -g < filename > 其中包含用户定义的磁盘组的文件,可以使用 filename 参数来指定此文件。文件中的每一行以组名开头。磁盘列表跟在组名后面,各个硬盘之间用空格分隔。该文件最多可包含 64 个磁盘组。硬盘可属于各种磁盘组。 -b 显示黑白方式的视图。 -B 不要在视图中包括框。缺省情况下该命令会显示框。 -h 显示帮助信息。 -k < disklist > 仅报告磁盘列表中的磁盘。 处于记录方式的标志 -A 在视图中包括异步 I/O 部分。 -c 指定此命令必须生成的快照数。缺省值为 10000000。 -d 在视图中包括磁盘服务时间部分。 -D 跳过磁盘配置部分。 -E 跳过 ESS 配置部分。 -f 指定输出使用电子表格格式。缺省情况下,此命令会生成系统数据的 288 个快照,两次生成快照之间的时间间隔为 300 秒。输出文件的名称为 hostname_YYMMDD_HHMM .nmon 格式。 -F 指定输出使用电子表格格式,并且输出文件的名称为 filename。filename 参数指定输出文件的名称。 -g 使用 filename 参数指定其中包含用户定义的磁盘组的文件。文件中的每一行以组名开头。磁盘列表跟在组名之后,磁盘之间用空格隔开。该文件最多可包含 64 个磁盘组。磁盘可属于各种磁盘组。 -G 使用格林威治标准时间(GMT)来代替当地时间。针对处理器视图比较来自一台机器的多个LPAR的 nmon 文件但LPAR在不同时区中时,这样做很有帮助。 -I 指定命令忽略最繁忙进程统计信息时的进程阈值百分比。缺省百分比为 0。如果进程使用的处理器资源低于给定百分比,那么该命令不会保存最繁忙进程统计信息。 -J 跳过 JFS 部分。 -k 指定要记录的磁盘的列表。 -K 在记录文件中包括 RAW 内核部分和LPAR部分。-K 标志会转储对应数据结构的原始数字。转储是可读的,并且可在命令记录数据时使用。 -l 指定每一行上要列示的磁盘数。缺省情况下,每行列示 150 个磁盘。对于 EMC 磁盘,指定值 64。 -L 包括大页分析部分。 -m 在命令将数据保存至文件之前切换目录。 -M 在记录文件中包括 MEMPAGES 部分。MEMPAGES 部分会显示对应每个页大小的详细内存统计信息。 -N 在记录文件中包括 NFS 部分。要收集 NFSv4 统计信息,请指定 -NN。 -o 指定要将已记录文件存储至的文件名或目录。 -O 在记录文件中包括共享以太网适配器(SEA)VIOS 部分。 -P 在记录文件中包括调页空间部分。 -r 指定写至电子表格文件的 runname 字段的值。缺省情况下,此值为 hostname。 -s 指定两个连续的记录快照之间的时间间隔(以秒计)。 -S 在记录文件中包括 WLM 部分以及子类。 -t 在输出中包括最繁忙进程。不能同时指定 -t、-T 或 -Y 标志当中的任意两者。 -T 在输出中包括最繁忙进程,并将这些命令行参数保存至 UARG 部分。不能同时指定 -t、-T 或 -Y 标志当中的任意两者。 -V 包括磁盘卷组部分。 -w 指定要记录的时间戳记的大小(Tnnnn)。时间戳记记录在 .csv 文件中。number 参数的值的范围是 4 到 16。对于 NMON 分析器,请使用值 4 或 8。 -W 在记录文件中包括 WLM 部分。 -x 指定持续时间为 1 天的可感电子表格记录以用于容量规划。缺省情况下,每 900 秒完成一次记录,一共完成 96 次。此标志相当于 -ft -s 900 -c 96。 -X 指定持续时间为 1 小时的可感电子表格记录以用于容量规划。缺省情况下,每 30 秒完成一次记录,一共完成 120 次。此标志相当于 -ft -s 30 -c 120。 -Y 在记录中包括最繁忙进程以及一起添加和记录的同名命令。不能同时指定 -t、-T 或 -Y 标志。 -z 指定持续时间为 1 天的可感电子表格记录以用于容量规划。缺省情况下,每 900 秒完成一次记录,一共完成 96 次。此标志相当于 -f -s 900 -c 96。 -Z 指定正在运行的 nmon 命令的优先级。值为 -20 时表示重要。值为 20 时表示不重要。只有 root 用户才能指定负值。 -^ 包括光纤通道(FC)部分。 参数 disklist 指定磁盘列表。 dir 指定目录。 dpl 指定每行上要列示的磁盘数。 filename 指定包含所选磁盘组的文件。 number 指定刷新次数。 count 指定记录次数。 percent 指定处理器使用资源的百分比。 priority 指定要运行的进程的优先级。 runname 指定要运行的电子表格文件中的 runname 字段的值。 seconds 指定刷新快照的时间间隔(以秒计)。 outputpath 指定输出文件的路径。 注:转载需注明出处及作者。 流柯
变量mynation从列表{"china", "US", "UK"}中随机取值 String[] nation = new String[]{"china", "US", "UK"}; Random random = new Random(); int i = random.nextInt(nation.length); vars.put("mynation",nation[i]); 在需要使用的 地方直接 ${mynation} 引用即可 如果要设置两个变量且变量值随机但不重复,可以通过两个列表放置不同值实现 String[] nation = new String[]{"china", "US", "UK"}; Random random = new Random(); int i = random.nextInt(nation.length); vars.put("mynation",nation[i]); String[] num = new String[]{"8", "2", "1","7"}; Random r = new Random(); int j = r.nextInt(num.length); vars.put("anum",num[j]); 注:转载需注明出处及作者。 流柯
为了给MYSQL用户设置远程连接权限,经历的种种错误总结 ERROR 2003 (HY00 原因是MySQL考虑到安全因素,默认配置只让从本地登录 打开 /etc/mysql/my.cnf 文件,找到 bind-address = 127.0.0.1 修改为 bind-address = 0.0.0.0 重启mysql : sudo /etc/init.d/mysql restart 再次连接,发生错误 1045 ERROR 1045 (28000): Access denied for user 'test'@'x.x.x.x' (using password: NO) A: 原因是没有给登录用户名设置远程主机登录的权限。还有种可能是你需要重设下密码....可能是授权操作引起这种后遗症.. 在本地用 root 登录: mysql -u root -p 修改 MySQL 数据库中 user 表中 对应用户名的 Host 字段,将 localhost 改为 % use mysql; update user set Host = '%' where User = 'username'; 给这个设置权限需要ROOT用户登录才行.可惜ROOT密码不记得了. 取回ROOT密码并设置远程登录 mysqld_safe --skip-grant-tables & mysql -u root mysql mysql> UPDATE user SET Password=PASSWORD('newpassword') where USER='root'; mysql> FLUSH PRIVILEGES; 设置 ROOT 远程连接 update user set host = '%' where user='root'; 查看进程,可看到MYSQLD_SAFE与MYSQL进程,此时MYSQL可正常使用,不过查看参数,可看到--skip-grant-tab 输入mysqld_safe命令行,要立马输入mysql -u root mysql,不得有误..或者新开一个窗口也可. 执行UPDATE时出现1062错误 RROR 1062 (23000): Duplicate entry '%-root' for key 'PRIMARY' 如果执行update语句时出现ERROR 1062 (23000): Duplicate entry '%-root' for key 'PRIMARY' 错误,说明有多个ROOT用户纪录在USER表中了. 需要select host from user where user = 'root'; 查看一下host是否已经有了%这个值,有了就可以了. mysql> select host,user from user where user='root'; +-----------------------+------+ | host | user | +-----------------------+------+ | % | root | | 127.0.0.1 | root | | ::1 | root | | localhost.localdomain | root | 然后用ROOT用户登录更改用户账户的远程连接权限时.出现提示:ERROR 1044 (42000): Access denied for user ''@'localhost' to database 'mysql'。 ERROR 1044 (42000): Access denied for user ''@'localhost' to database 'mysql'。 是因为mysql数据库的user表里,存在用户名为空的账户即匿名账户,导致登录的时候是虽然用的是root,但实际是匿名登录的,通过错误提示里的''@'localhost'可以看出来,于是解决办法见 先关闭MYSQL进程.. 然后 # mysqld_safe --skip-grant-table 屏幕出现: Starting demo from ..... 此时要记得,紧接着输入 # mysql -u root mysql mysql> delete from user where USER=''; mysql> FLUSH PRIVILEGES; 如果出现 Starting demo from .. 后..先输入其它命令,再用mysql -u root mysql .它又会出现这个错误了. 然后KILL掉MYSQL进程,..重启正常的进程.. 设置用户远程主机连接权限 update user set host = '%' where user='fanzkcom_fanzk'; FLUSH PRIVILEGES; 但是在实际连接中,虽然可以连接,但是去没有所在库的权限,晕. 只好接下来设置权限 设置用户与库的权限 grant all privileges on fanzkcom_fanzk.* to fanzkcom_fanzk@'%' identified by '1234'; FLUSH PRIVILEGES; 百分号两边要有单引号,否则语法错误 然后连接时,竟然提示1045 错误了.晕,,想了半天,还是重设下密码试下. update mysql.user set password=password('XXX') where User="fanzkcom_fanzk" flush privileges; 注:转载需注明出处及作者。 流柯
系统环境:Centos 6.8 第一步:通过yum命令安装svnserve,命令如下: >yum -y install subversion 此命令会全自动安装svn服务器相关服务和依赖,安装完成会自动停止命令运行 若需查看svn安装位置,可以用以下命令: >rpm -ql subversion 第二步:创建版本库目录(此仅为目录,为后面创建版本库提供存放位置) 选择在var路径下创建版本库,当前处于根目录下,一次性创建如下: >mkdir -p /var/svn/svnrepos 第三步:创建svn版本库 在第二步建立的路径基础上,创建版本库,命令如下: >svnadmin create /var/svn/svnrepos/liuke (xxxx为自定义版本库名称,可根据实际情况填写) 创建成功后,进入/var/svn/svnrepos/liuke目录下 >cd /var/svn/svnrepos/liuke 进入目录,可以看见如下文件信息: 第四步:配置修改 进入已经创建好的版本库目录下,也就是前文说创建的xxxx 进入conf >cd /var/svn/svnrepos/liuke/conf conf目录下,一共存放三份重要的配置文件,如下: authz:负责账号权限的管理,控制账号是否读写权限 passwd:负责账号和密码的用户名单管理 svnserve.conf:svn服务器配置文件 细节修改如下:(希望大家严格按照以下信息,不用参考网络上其他资料) 修改authz文件信息,如下: >vi authz 在文件内容的末尾,添加如下: 只需在末尾添加,无需在文件其他部分修改和添加任何东西(请忽略groups被我马赛克的地方,那其实也是条无用的记录,我忘记删掉而已),末尾内容如下: [\] 账号1 = rw 账号2 = rw 。。。。。 rw表示赋予此账号可读写的权限,请注意[]中的斜杠,一定是反斜杠,有些教程说,需添加版本库名称在括号内,我直接建议就这写,这样写允许访问的权限更大,避免一些错误 修改passwd文件信息 >vi passwd 账号密码文件无需做修改,也是直接将账号和密码信息追加到文件中即可,注意格式为: 账号 = 密码 例如:liuke = 123456 修改svnserve.conf(重要) vi svnserve.conf 原始文件内容,都被注释掉的,我们只需要去掉4条指定内容前注释即可,如下: 大多数网络资料,都会让大家将authz-db = authz这条给去掉注释,经过我本人多次被坑经验,此条去掉后,虽然svn服务器可以连接,但一直会提示“认证失败”,注释掉即可正常 还有多数资料会让大家在realm = My First Repository处填写服务器ip,经过测试,填写后并无什么用处,所以大家去掉注释即可,无需做任何修改 到此,配置已经全部完成,账号信息已经添加成功 第五步:防火墙开启 多数情况下服务器安装完成,配置完成后,无法连接svn服务器,均是防火墙问题,大家按照如下3条命令逐一执行即可 >/sbin/iptables -I INPUT -p tcp --dport 3690 -j ACCEPT >/etc/init.d/iptables save >service iptables restart 执行结果如下图: 六:启动svn服务器 在跟目录下,执行如下命令: >svnserve -d -r /var/svn/svnrepos 启动成功后,可用ps -aux查看服务启动是否成功 七:客户端访问svn服务器 在windows客户端,输入地址:svn://ip地址:3690/liuke (iP地址为你linux的ip,liuke为前文创建的版本库名称,3690为svn默认端口) 弹出输入用户名和密码,输入即可访问 注:转载需注明出处及作者。 流柯
Docker是一个开源的应用容器引擎,可以轻松的为任何应用创建一个轻量级的、可移植的、自给自足的容器。利用Linux的LXC、AUFS、Go语言、cgroup实现了资源的独立,可以很轻松的实现文件、资源、网络等隔离,其最终的目标是实现类似PaaS平台的应用隔离。 Docker值得关注的特性: 文件系统隔离:每个进程容器运行在一个完全独立的根文件系统里。 资源隔离:系统资源,像CPU和内存等可以分配到不同的容器中,使用cgroup。 网络隔离:每个进程容器运行在自己的网络空间,虚拟接口和IP地址。 日志记录:Docker将会收集和记录每个进程容器的标准流(stdout/stderr/stdin),用于实时检索或批量检索。 变更管理:容器文件系统的变更可以提交到新的映像中,并可重复使用以创建更多的容器。无需使用模板或手动配置。 交互式shell:Docker可以分配一个虚拟终端并关联到任何容器的标准输入上,例如运行一个一次***互shell。 Docker通常用于如下场景: web应用的自动化打包和发布; 自动化测试和持续集成、发布; 在服务型环境中部署和调整数据库或其他的后台应用; 从头编译或者扩展现有的OpenShift或Cloud Foundry平台来搭建自己的PaaS环境。 我这里用的是CentOS6.8。 注意:其他的源可能导致你的内核和docker的版本不一致,需要升级内核至3.x。 安装: 1 [root@localhost ~]# rpm -ivh http://dl.Fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm 2 Retrieving http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm 3 warning: /var/tmp/rpm-tmp.JN76fI: Header V3 RSA/SHA256 Signature, key ID 0608b895: NOKEY 4 Preparing... ########################################### [100%] 5 1:epel-release ########################################### [100%] 6 [root@localhost ~]# rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-6 7 8 [root@localhost ~]# yum -y install docker-io 9 10 启动并设置开机自动启动 11 12 [root@localhost ~]# service docker start 13 Starting cgconfig service: [确定] 14 Starting docker: [确定] 15 [root@localhost ~]# chkconfig docker on 获取centos镜像 [root@localhost ~]# docker pull hub.c.163.com/public/centos:6.7 官方安装方式docker pull imagename从docker的索引中心下载,imagename是镜像名称,例如docker pull Ubuntu就是下载base ubuntu并且tag是latest。 由于国内访问直接访问Docker hub网速比较慢,拉取镜像的时间就会比较长。一般我们会使用镜像加速或者直接从国内的一些平台镜像仓库上拉取。 列出两个常用的: 网易镜像中心:https://c.163.com/hub#/m/home/ daocloud镜像市场:https://hub.daocloud.io/ 查看docker镜像 运行docker运行shell 查看容器信息 停止容器 [root@localhost ~]# docker stop <CONTAINER ID> 删除容器(docker rm): docker ps -a #获取容器name docker rm container_name 删除所有容器 docker rm $(docker ps -a -q) 刚接触。 注:转载需注明出处及作者。 流柯
方法一:手动解压JDK的压缩包,然后设置环境变量 1.在/usr/目录下创建java目录 [root@localhost ~]# mkdir/usr/java [root@localhost ~]# cd /usr/java 2.下载jdk,然后解压 [root@localhost java]# curl -O http://download.Oracle.com/otn-pub/java/jdk/7u79-b15/jdk-7u79-linux-x64.tar.gz [root@localhost java]# tar -zxvf jdk-7u79-linux-x64.tar.gz 3.设置环境变量 [root@localhost java]# vi /etc/profile 在profile中添加如下内容: #set java environment JAVA_HOME=/usr/java/jdk1.7.0_79 JRE_HOME=/usr/java/jdk1.7.0_79/jre CLASS_PATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib PATH=$PATH:$JAVA_HOME/bin:$JRE_HOME/bin export JAVA_HOME JRE_HOME CLASS_PATH PATH 让修改生效: [root@localhost java]# source /etc/profile 4.验证JDK有效性 [root@localhost java]# java -version java version "1.7.0_79" Java(TM) SE Runtime Environment (build 1.7.0_79-b15) Java HotSpot(TM) 64-Bit Server VM (build 24.79-b02, mixed mode) 方法二:用yum安装JDK 1.查看yum库中都有哪些jdk版本(暂时只发现了openjdk) [root@localhost ~]# yum search java|grep jdk ldapjdk-javadoc.x86_64 : Javadoc for ldapjdk java-1.6.0-openjdk.x86_64 : OpenJDK Runtime Environment java-1.6.0-openjdk-demo.x86_64 : OpenJDK Demos java-1.6.0-openjdk-devel.x86_64 : OpenJDK Development Environment java-1.6.0-openjdk-javadoc.x86_64 : OpenJDK API Documentation java-1.6.0-openjdk-src.x86_64 : OpenJDK Source Bundle java-1.7.0-openjdk.x86_64 : OpenJDK Runtime Environment java-1.7.0-openjdk-demo.x86_64 : OpenJDK Demos java-1.7.0-openjdk-devel.x86_64 : OpenJDK Development Environment java-1.7.0-openjdk-javadoc.noarch : OpenJDK API Documentation java-1.7.0-openjdk-src.x86_64 : OpenJDK Source Bundle java-1.8.0-openjdk.x86_64 : OpenJDK Runtime Environment java-1.8.0-openjdk-demo.x86_64 : OpenJDK Demos java-1.8.0-openjdk-devel.x86_64 : OpenJDK Development Environment java-1.8.0-openjdk-headless.x86_64 : OpenJDK Runtime Environment java-1.8.0-openjdk-javadoc.noarch : OpenJDK API Documentation java-1.8.0-openjdk-src.x86_64 : OpenJDK Source Bundle ldapjdk.x86_64 : The Mozilla LDAP Java SDK 2.选择版本,进行安装 //选择1.7版本进行安装 [root@localhost ~]# yum install java-1.7.0-openjdk //安装完之后,默认的安装目录是在: /usr/lib/jvm/java-1.7.0-openjdk-1.7.0.75.x86_64 3.设置环境变量 [root@localhost ~]# vi /etc/profile 在profile文件中添加如下内容 #set java environment JAVA_HOME=/usr/lib/jvm/java-1.7.0-openjdk-1.7.0.75.x86_64 JRE_HOME=$JAVA_HOME/jre CLASS_PATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib PATH=$PATH:$JAVA_HOME/bin:$JRE_HOME/bin export JAVA_HOME JRE_HOME CLASS_PATH PATH 让修改生效 [root@localhost java]# source /etc/profile 4.验证(同上一方法) 方法三:用rpm安装JDK 1.下载rpm安装文件 [root@localhost ~]$ curl -O http://download.oracle.com/otn-pub/java/jdk/7u79-b15/jdk-7u79-linux-x64.rpm 2.使用rpm命令安装 [root@localhost ~]# rpm -ivh jdk-7u79-linux-x64.rpm 3.设置环境变量 [root@localhost java]# vi /etc/profile 在打开的profile文件中添加如下内容 #set java environment JAVA_HOME=/usr/java/jdk1.7.0_79 JRE_HOME=/usr/java/jdk1.7.0_79/jre CLASS_PATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib PATH=$PATH:$JAVA_HOME/bin:$JRE_HOME/bin export JAVA_HOME JRE_HOME CLASS_PATH PATH 让修改生效 [root@localhost java]# source /etc/profile 4.验证(同上一方法) 注:和yum安装类似,不用设置环境变量就可以运行java命令。rpm安装方式默认会把jdk安装到/usr/java/jdk1.7.0_79,然后通过三层链接,链接到/usr/bin,具体链接如下: [root@localhost ~]# cd /bin [root@localhost bin]# ll|grep java lrwxrwxrwx. 1 root root 25 Mar 28 11:24 jar ->/usr/java/default/bin/jar lrwxrwxrwx. 1 root root 26 Mar 28 11:24 java -> /usr/java/default/bin/java lrwxrwxrwx. 1 root root 27 Mar 28 11:24 javac ->/usr/java/default/bin/javac lrwxrwxrwx. 1 root root 29 Mar 28 11:24 javadoc ->/usr/java/default/bin/javadoc lrwxrwxrwx. 1 root root 28 Mar 28 11:24 javaws ->/usr/java/default/bin/javaws lrwxrwxrwx. 1 root root 30 Mar 28 11:24 jcontrol ->/usr/java/default/bin/jcontrol [root@localhost bin]# cd /usr/java/ [root@localhost java]# ll total 4 lrwxrwxrwx. 1 root root 16 Mar 28 11:24 default-> /usr/java/latest drwxr-xr-x. 8 root root 4096 Mar 28 11:24 jdk1.7.0_79 lrwxrwxrwx. 1 root root 21 Mar 28 11:24 latest -> /usr/java/jdk1.7.0_79 注:转载需注明出处及作者。 流柯
由于编码原因,在linux服务器上上传、创建中文文件或目录时,会产生乱码,如果想删除它,发现用rm命令是删除不了的 这种情况下,用find命令可以删除乱码的文件或目录。 首先进入乱码文件或目录所在的目录 使用ls -i命令找到文件或目录的inode, 文件或目录前面的数字字符串就是inode, 接下来使用find命令查询并且删除此文件或目录 注意:此方法只适用于删除文件或空的文件夹。 非空文件夹怎么删除呢? 首先也是先查inode, 然后用如下命令即可: find -inum 2236429 -exec rm -rf {} \; 会提示找不到此文件或文件夹,但其实已经删除了。 注:转载需注明出处及作者。 流柯
自旋锁与互斥锁有点类似,只是自旋锁不会引起调用者睡眠,如果自旋锁已经被别的执行单元保持,调用者就一直循环在那里看是否该自旋锁的保持者已经释放了锁,"自旋"一词就是因此而得名。 由于自旋锁使用者一般保持锁时间非常短,因此选择自旋而不是睡眠是非常必要的,自旋锁的效率远高于互斥锁。 信号量和读写信号量适合于保持时间较长的情况,它们会导致调用者睡眠,因此只能在进程上下文使用(_trylock的变种能够在中断上下文使用),而自旋锁适合于保持时间非常短的情况,它可以在任何上下文使用。 如果被保护的共享资源只在进程上下文访问,使用信号量保护该共享资源非常合适,如果对共巷资源的访问时间非常短,自旋锁也可以。但是如果被保护的共享资源需要在中断上下文访问(包括底半部即中断处理句柄和顶半部即软中断),就必须使用自旋锁。 自旋锁保持期间是抢占失效的,而信号量和读写信号量保持期间是可以被抢占的。自旋锁只有在内核可抢占或SMP的情况下才真正需要,在单CPU且不可抢占的内核下,自旋锁的所有操作都是空操作。 跟互斥锁一样,一个执行单元要想访问被自旋锁保护的共享资源,必须先得到锁,在访问完共享资源后,必须释放锁。如果在获取自旋锁时,没有任何执行单元保持该锁,那么将立即得到锁;如果在获取自旋锁时锁已经有保持者,那么获取锁操作将自旋在那里,直到该自旋锁的保持者释放了锁。 无论是互斥锁,还是自旋锁,在任何时刻,最多只能有一个保持者,也就说,在任何时刻最多只能有一个执行单元获得锁。 自旋锁的API有: spin_lock_init(x) 该宏用于初始化自旋锁x。自旋锁在真正使用前必须先初始化。该宏用于动态初始化。 DEFINE_SPINLOCK(x) 该宏声明一个自旋锁x并初始化它。该宏在2.6.11中第一次被定义,在先前的内核中并没有该宏。 SPIN_LOCK_UNLOCKED 该宏用于静态初始化一个自旋锁。 DEFINE_SPINLOCK(x)等同于spinlock_t x = SPIN_LOCK_UNLOCKED spin_is_locked(x) 该宏用于判断自旋锁x是否已经被某执行单元保持(即被锁),如果是,返回真,否则返回假。 spin_unlock_wait(x) 该宏用于等待自旋锁x变得没有被任何执行单元保持,如果没有任何执行单元保持该自旋锁,该宏立即返回,否则将循环在那里,直到该自旋锁被保持者释放。 spin_trylock(lock) 该宏尽力获得自旋锁lock,如果能立即获得锁,它获得锁并返回真,否则不能立即获得锁,立即返回假。它不会自旋等待lock被释放。 spin_lock(lock) 该宏用于获得自旋锁lock,如果能够立即获得锁,它就马上返回,否则,它将自旋在那里,直到该自旋锁的保持者释放,这时,它获得锁并返回。总之,只有它获得锁才返回。 spin_lock_irqsave(lock, flags) 该宏获得自旋锁的同时把标志寄存器的值保存到变量flags中并失效本地中断。 spin_lock_irq(lock) 该宏类似于spin_lock_irqsave,只是该宏不保存标志寄存器的值。 spin_lock_bh(lock) 该宏在得到自旋锁的同时失效本地软中断。 spin_unlock(lock) 该宏释放自旋锁lock,它与spin_trylock或spin_lock配对使用。如果spin_trylock返回假,表明没有获得自旋锁,因此不必使用spin_unlock释放。 spin_unlock_irqrestore(lock, flags) 该宏释放自旋锁lock的同时,也恢复标志寄存器的值为变量flags保存的值。它与spin_lock_irqsave配对使用。 spin_unlock_irq(lock) 该宏释放自旋锁lock的同时,也使能本地中断。它与spin_lock_irq配对应用。 spin_unlock_bh(lock) 该宏释放自旋锁lock的同时,也使能本地的软中断。它与spin_lock_bh配对使用。 spin_trylock_irqsave(lock, flags) 该宏如果获得自旋锁lock,它也将保存标志寄存器的值到变量flags中,并且失效本地中断,如果没有获得锁,它什么也不做。 因此如果能够立即获得锁,它等同于spin_lock_irqsave,如果不能获得锁,它等同于spin_trylock。如果该宏获得自旋锁lock,那需要使用spin_unlock_irqrestore来释放。 spin_trylock_irq(lock) 该宏类似于spin_trylock_irqsave,只是该宏不保存标志寄存器。如果该宏获得自旋锁lock,需要使用spin_unlock_irq来释放。 spin_trylock_bh(lock) 该宏如果获得了自旋锁,它也将失效本地软中断。如果得不到锁,它什么也不做。因此,如果得到了锁,它等同于spin_lock_bh,如果得不到锁,它等同于spin_trylock。如果该宏得到了自旋锁,需要使用spin_unlock_bh来释放。 spin_can_lock(lock) 该宏用于判断自旋锁lock是否能够被锁,它实际是spin_is_locked取反。如果lock没有被锁,它返回真,否则,返回假。该宏在2.6.11中第一次被定义,在先前的内核中并没有该宏。 获得自旋锁和释放自旋锁有好几个版本,因此让读者知道在什么样的情况下使用什么版本的获得和释放锁的宏是非常必要的。 如果被保护的共享资源只在进程上下文访问和软中断上下文访问,那么当在进程上下文访问共享资源时,可能被软中断打断,从而可能进入软中断上下文来对被保护的共享资源访问,因此对于这种情况,对共享资源的访问必须使用spin_lock_bh和spin_unlock_bh来保护。 当然使用spin_lock_irq和spin_unlock_irq以及spin_lock_irqsave和spin_unlock_irqrestore也可以,它们失效了本地硬中断,失效硬中断隐式地也失效了软中断。但是使用spin_lock_bh和spin_unlock_bh是最恰当的,它比其他两个快。 如果被保护的共享资源只在进程上下文和tasklet或timer上下文访问,那么应该使用与上面情况相同的获得和释放锁的宏,因为tasklet和timer是用软中断实现的。 如果被保护的共享资源只在一个tasklet或timer上下文访问,那么不需要任何自旋锁保护,因为同一个tasklet或timer只能在一个CPU上运行,即使是在SMP环境下也是如此。实际上tasklet在调用tasklet_schedule标记其需要被调度时已经把该tasklet绑定到当前CPU,因此同一个tasklet决不可能同时在其他CPU上运行。 timer也是在其被使用add_timer添加到timer队列中时已经被帮定到当前CPU,所以同一个timer绝不可能运行在其他CPU上。当然同一个tasklet有两个实例同时运行在同一个CPU就更不可能了。 如果被保护的共享资源只在两个或多个tasklet或timer上下文访问,那么对共享资源的访问仅需要用spin_lock和spin_unlock来保护,不必使用_bh版本,因为当tasklet或timer运行时,不可能有其他tasklet或timer在当前CPU上运行。 如果被保护的共享资源只在一个软中断(tasklet和timer除外)上下文访问,那么这个共享资源需要用spin_lock和spin_unlock来保护,因为同样的软中断可以同时在不同的CPU上运行。 如果被保护的共享资源在两个或多个软中断上下文访问,那么这个共享资源当然更需要用spin_lock和spin_unlock来保护,不同的软中断能够同时在不同的CPU上运行。 如果被保护的共享资源在软中断(包括tasklet和timer)或进程上下文和硬中断上下文访问,那么在软中断或进程上下文访问期间,可能被硬中断打断,从而进入硬中断上下文对共享资源进行访问,因此,在进程或软中断上下文需要使用spin_lock_irq和spin_unlock_irq来保护对共享资源的访问。 而在中断处理句柄中使用什么版本,需依情况而定,如果只有一个中断处理句柄访问该共享资源,那么在中断处理句柄中仅需要spin_lock和spin_unlock来保护对共享资源的访问就可以了。 因为在执行中断处理句柄期间,不可能被同一CPU上的软中断或进程打断。但是如果有不同的中断处理句柄访问该共享资源,那么需要在中断处理句柄中使用spin_lock_irq和spin_unlock_irq来保护对共享资源的访问。 在使用spin_lock_irq和spin_unlock_irq的情况下,完全可以用spin_lock_irqsave和spin_unlock_irqrestore取代,那具体应该使用哪一个也需要依情况而定,如果可以确信在对共享资源访问前中断是使能的,那么使用spin_lock_irq更好一些。 因为它比spin_lock_irqsave要快一些,但是如果你不能确定是否中断使能,那么使用spin_lock_irqsave和spin_unlock_irqrestore更好,因为它将恢复访问共享资源前的中断标志而不是直接使能中断。 当然,有些情况下需要在访问共享资源时必须中断失效,而访问完后必须中断使能,这样的情形使用spin_lock_irq和spin_unlock_irq最好。 spin_lock用于阻止在不同CPU上的执行单元对共享资源的同时访问以及不同进程上下文互相抢占导致的对共享资源的非同步访问,而中断失效和软中断失效却是为了阻止在同一CPU上软中断或中断对共享资源的非同步访问。 注:转载需注明出处及作者。 流柯
对.py文件支持右键用UliPad打开方式支持: 1.打开注册表(win+R,运行框输入regedit) 2.先对*.py文件进行设置。找到注册表目录HKEY_CLASSES_ROOT\Python.File\shell,在shell文件夹图标上点右键→新建→项,对新项进行命名,这里命什么名 字,在右键将会显示什么名字,比如我的是“Edit with UliPad”。 3.在“Edit with UliPad”上继续点右键新建项,项名为“command”,点command,右边出现一个“默认”,后面的数据是空的,现在就是在这里添加数据。 4.双击“默认"弹出编辑对话框,复制以下字符: "C:\Program Files\UliPad\UliPad.exe" "%1" 即可。 注:转载需注明出处及作者。 流柯
一、MySQL建库和建账号 1、 mysql中创建数据库jiradb create database jiradb character set 'UTF8'; 2、创建数据库用户并赋于权限 create user jirauser identified by 'jira'; //创建用户名为jirauser,密码为jira的帐号 grant all privileges on *.* to 'jirauser'@'%' identified by 'jira' with grant option; grant all privileges on *.* to 'jirauser'@'localhost' identified by 'jira' with grant option; flush privileges; quit; 二、安装JIRA 1、双击:atlassian-jira-6.3.6-x32.exe 2、点击Next 3、选择安装模式: Express Install(use default settings):使用默认安装选项 Custom install(recommended for advanced users):自定义安装 Upgrade an existing JIRA installation:升级安装 此处选择:Custom install(recommended for advanced users) 4、JIRA安装路径 5、JIRA数据路径 6、选择并创建开始菜单 7、端口设置。 如果有多个应用最好自定义端口号,此处选择自定义,设置端口号为:8888 8、JIRA作为服务安装(随系统启动服务就自动启动,不打勾就要手动启动) 9、安装中。。。 10、安装结束。 到此,只是安装成功。 三、安装mysql驱动 1、先将JIRA服务关掉 2、拷贝数据驱动mysql-connector-java-5.1.25-bin.jar到jira安装目录下的lib目录 3、再启动JIRA服务。 四、配置与破解jira 1、设置数据库,IE中打开:http://localhost:8888,这里不选第一个自带数据库,这里用的是MySQL。 输入完毕后点击:Test Connection,如果显示下图头部的信息,说明连接MySQL成功。然后点击:Next 2、点击“Test Connection”,如下图: 3、点击Next,如下图: 4、设置应用属性 5、Customize Your Installation,选择第二项,如下图: 6、输入授权码。 到了这一步,就是破解的过程了,此时操作如下: 1)先将JIRA服务关掉,不必关闭浏览器。 2)解压破解包到你的硬盘指定目录下,然后按如下指令操作。 用atlassian-extras-2.2.2.jar替换你的JIRA的安装目录的\atlassian-jira\WEB-INF\lib同名jar包。 用atlassian-universal-plugin-manager-plugin-2.10.1.jar替换你的JIRA的安装目录的\atlassian-jira\atlassian-bundled-plugins.zip中的同名jar包。 根据自己的情况,按照keytpl.txt的格式填写好自己的license。 Description=JIRA: Commercial, CreationDate=2015-04-22, jira.LicenseEdition=ENTERPRISE, Evaluation=false, jira.LicenseTypeName=COMMERCIAL, jira.active=true, licenseVersion=2, MaintenanceExpiryDate=2099-12-31, Organisation=saper, SEN=SEN-L4140432, ServerID=BVQA-MV0B-21MB-5YPM, jira.NumberOfUsers=-1, LicenseID=LIDSEN-L4140432, LicenseExpiryDate=2099-12-31, PurchaseDate=2015-04-22 3)启动JIRA服务 4)在浏览器网页的输入License,点击Next 7、设置管理员帐户 8、设置Email通知。这里跳过,之后在界面中也可以设置。 进入页面,如果查看到以下页面,就表明破解成功。 五、JIRA汉化 1、先将JIRA服务关掉 2、直接将language_zh_CN-6.0.jar拷贝到JIRA的安装目录的\atlassian-jira\WEB-INF\lib说明:JIRA提供了官方的中文包(汉化了60%),可通过web页面的插件管理安装官方的中文包。 3、再启动JIRA服务 访问页面如下图: 注:转载需注明出处及作者。 流柯
有的时候不同job直接需要传递一个文件名或者路径,这个时候我们不需要传递文件实体,那这个路径如何传递呢?比如有如下两个项目,我想把A的工作目录传递给B,让B使用。 A job配置 首先需要安装一个Parameterized Trigger Plugin插件: 安装后重启。 在A项目配置面板中Post-build Actions选项中选择Trigger parameterized build on other projects 我选择的参数为预定义参数,如果想知道有哪些与定义参数,可以在Build模块下选择Execute shell 选在文本框下的the list of available environment variables 选项,可以查看如下信息: The following variables are available to shell scripts BUILD_NUMBER The current build number, such as "153" BUILD_ID The current build id, such as "2005-08-22_23-59-59" (YYYY-MM-DD_hh-mm-ss) BUILD_DISPLAY_NAME The display name of the current build, which is something like "#153" by default. JOB_NAME Name of the project of this build, such as "foo" or "foo/bar". (To strip off folder paths from a Bourne shell script, try: ${JOB_NAME##*/}) BUILD_TAG String of "jenkins-${JOB_NAME}-${BUILD_NUMBER}". Convenient to put into a resource file, a jar file, etc for easier identification. EXECUTOR_NUMBER The unique number that identifies the current executor (among executors of the same machine) that’s carrying out this build. This is the number you see in the "build executor status", except that the number starts from 0, not 1. NODE_NAME Name of the slave if the build is on a slave, or "master" if run on master NODE_LABELS Whitespace-separated list of labels that the node is assigned. WORKSPACE The absolute path of the directory assigned to the build as a workspace. JENKINS_HOME The absolute path of the directory assigned on the master node for Jenkins to store data. JENKINS_URL Full URL of Jenkins, like http://server:port/jenkins/ (note: only available if Jenkins URL set in system configuration) BUILD_URL Full URL of this build, like http://server:port/jenkins/job/foo/15/ (Jenkins URL must be set) JOB_URL Full URL of this job, like http://server:port/jenkins/job/foo/ (Jenkins URL must be set) SVN_REVISION Subversion revision number that's currently checked out to the workspace, such as "12345" SVN_URL Subversion URL that's currently checked out to the workspace. ok,回到正题,具体配置如下: 我将A项目的工作目录传递给了自定义参数TEST_WORKSPACE.到这里A项目的配置就完成了。 B job配置 我们在A项目配置的TEST_WORKSPACE参数,如果在B job中使用,首先我们在配置界面中,勾选The build is parameterized。具体配置信息如下所示: 这样我们就在当前工作环境中得到了由A传递过来的参数。至于你怎么使用,那是你的事了。比如我在shell脚本中首先切换到该目录下(需要在一台机器上),然后在A项目的工作目录下生成一个hello.txt文档,我们可以在shell命令下配置如下信息: ok,配置完成了,这个时候我们构建A,看看能不能让B在A的工作目录下生成一个hello.txt文档。 Done! 注:转载需注明出处及作者。 流柯
用例设计: 执行用例代码:# -*- coding: UTF-8 -*-import xlrd,logging,urllib,urllib2,json,sysfrom pylsy import pylsytable########################################################################################################定义系统输出编码reload(sys)sys.setdefaultencoding('utf-8')##########################################################################################################定义日志输出logging.basicConfig(level=logging.DEBUG, format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s', datefmt='%a, %d %b %Y %H:%M:%S', filename='myapp.log', filemode='w')##################################################################################################定义一个StreamHandler,将INFO级别或更高的日志信息打印到标准错误,并将其添加到当前的日志处理对象#console = logging.StreamHandler()console.setLevel(logging.INFO)formatter = logging.Formatter('%(name)-12s: %(levelname)-8s %(message)s')console.setFormatter(formatter)logging.getLogger('').addHandler(console)#####################################################################################################################################################################################################处理excel表格data = xlrd.open_workbook('C:\Users\xxxxx\Desktop\API.xls')#打开excel表格logging.info("打开%s excel表格成功"%data)table = data.sheet_by_name(u'Sheet2')#打开工作表sheet2logging.info("打开%s表成功"%table)nrows = table.nrows#统计行数logging.info("表中有%s行"%nrows)ncols = table.ncols#统计列数logging.info("表中有%s列"%ncols)logging.info("开始进行循环")name_1=[];url_1=[];params_1=[];type_1=[];Expected_result_1=[];Actual_result_1 =[];test_result_1=[];Remarks_1=[]#定义数组Success=0;fail=0 #初始化成功失败用例##################################################################################################################for i in range(1,nrows):#遍历excel表格 cell_A3 =table.row_values(i)#获取excel表格中的数据 name = cell_A3[0] url = cell_A3[1] params=eval(cell_A3[2]) type = cell_A3[3] error_code =cell_A3[4] Remarks =cell_A3[5] logging.info(url)#############################################################################################################################3 params =urllib.urlencode(params) #参数化处理 logging.info(params) url2 = urllib2.Request(url,params) print "***********开始执行请求************" response = urllib2.urlopen(url2) logging.info(response) apicontent = response.read() logging.info(apicontent) apicontent = json.loads(apicontent)#验证返回值 if apicontent["error_code"]==int(error_code): name2="通过" print name+"测试通过" else: name2="失败" print name+"测试失败" name_1.append(name) url_1.append(url) params_1.append(params) type_1.append(type) Expected_result_1.append(int(error_code)) Actual_result_1.append(apicontent["error_code"]) test_result_1.append(name2) Remarks_1.append(Remarks) if name2=="通过": Success+=1 elif name2=="失败": fail +=1 else: print "测试结果异常"###############################################################################################################################输出表格形式attributes =["urlname","url","params","type","Expected_result","Actual_result","test_result","Remarks"]table =pylsytable(attributes)name =name_1url =url_1params=params_1type=type_1Expected_result=Expected_result_1Actual_result =Actual_result_1test_result=test_result_1Remarks=Remarks_1table.add_data("urlname",name)table.add_data("url",url)table.add_data("params",params)table.add_data("type",type)table.add_data("Expected_result",Expected_result)table.add_data("Actual_result",Actual_result)table.add_data("test_result",test_result)table.add_data("Remarks",Remarks)table._create_table()print tableprint "成功的用例个数为:%s"%Success,"失败的用例个数为:%s"%failprint "***********执行测试成功************"执行结果: 注:转载需注明出处及作者。 流柯
jmeter能用来做参数化的组件有几个,但是都没有随机取值的功能,遇到随机取值的需求怎么办呢? 突发奇想,可以用函数__CSVRead()来实现: __CSVRead() CSV file to get values from | *alias:表示要读取的文件路径 CSV文件列号| next| *alias:表示当前变量读取第几列数据,注意第一列是0; 由此可见我们只需将参数化数据在csv中横向排列,然后用随机函数__Random()指定文件序列号即可。 ${__CSVRead(D:\t.txt,${__Random(1,6,)})} t.txt文件内容:a,s,d,f,g,h 这样即可随机取到t.txt文件中的数据。 注:转载需注明出处及作者。 流柯
插件开发方法有两种: 一、在jmeter官网下载jmeter源码,在源码里面新加函数,然后导出jar; 二、不下载源码,直接导入jmeter相应的jar包,即可开发。(推荐) 下面介绍第二种开发方法: 在eclipse新建项目,导入jmeter目录下\lib\ext目录中的的ApacheJMeter_core.jar,继承AbstractFunction类。 案例:以下写一个计算阶乘的Function,将其命名为Factorial,主要代码参考如下, import java.util.Collection; import java.util.LinkedList; import java.util.List; import org.apache.jmeter.engine.util.CompoundVariable; import org.apache.jmeter.functions.AbstractFunction; import org.apache.jmeter.functions.InvalidVariableException; import org.apache.jmeter.samplers.SampleResult; import org.apache.jmeter.samplers.Sampler; import org.apache.jmeter.util.JMeterUtils; import org.apache.jorphan.logging.LoggingManager; import org.apache.log.Logger; public class Factorial extends AbstractFunction { private static final Logger log = LoggingManager.getLoggerForClass(); private static final List<String> desc = new LinkedList<String>(); private static final String KEY = "__factorial"; private Object[] values = null; static { desc.add("factorial_value"); } //描述参数 @Override public List<String> getArgumentDesc() { // TODO Auto-generated method stub return desc; } //函数执行,返回结果 @Override public String execute(SampleResult previousResult, Sampler currentSampler) throws InvalidVariableException { // TODO Auto-generated method stub String numberString = ((CompoundVariable) values[0]).execute().trim(); int num; try{ num = Integer.valueOf(numberString); } catch (Exception e){ return null; } return String.valueOf(factorial(num)); } //获取函数引用关键字 @Override public String getReferenceKey() { // TODO Auto-generated method stub return KEY; } //设置参数 @Override public void setParameters(Collection<CompoundVariable> parameters) throws InvalidVariableException { // TODO Auto-generated method stub //可以检查参数数量,主要包括以下两种方法 checkMinParameterCount(parameters, 1); checkParameterCount(parameters, 1, 1); values = parameters.toArray(); } private int factorial(int num){ int result = 1; if(num < 0){ return -1; } if(num == 0){ result = 1; } else { for(int i = num; i > 0; i--){ result *= i; } } return result; } } 通过继承AbstractFunction抽象类,重写getArgumentDesc方法实现对函数参数的描述,重写setParameters方法来对函数的参数进行检查和设置,重写getReferenceKey方法告诉JMeter该函数在框架中的引用名称,重写execute方法,实现对该函数的执行并返回结果。通过上述代码我们完成了对Factorial函数组件的编写。 将代码导出为jar文件,放在\lib\ext目录中,打开jmeter即可在函数助手中查看到该函数组件: 注:转载需注明出处及作者。 流柯