qileilove

blog已经转移至github,大家请访问 http://qaseven.github.io/

jmeter之配置元件

利用Jmeter的http请求的时候,例如登陆操作,我们做普通用户名和密码作参数化,循环读取文本里的用户名和密码,可以添加CSV Data Set Config这个原件来控制。

利用Jmeter的CSV Data Set Config,可以实现这个功能,具体如下:

1.新建一个文本文件,里面保存要登录的用户名,密码,文件内容如下:

baidu,123456

coolsin,liujuan

sb,123456

说明:这里用英文逗号为分隔符,也可以用其他为分隔符,在CSV Data Set Config中可以设置。如果此文本文件为CSV格式的,则用豆号分格

2.右键点击Jmeter中需要参数化的某个请求,选择添加——配置原件——CSV Data Set Config,会添加一个CSV Data Set Config,需要设置相关的一些内容,具体如下:

Filename:文件名,,指保存信息的文件目录,可以相对或者绝对路径(比如:D:\user.csv)

Variable Names:参数名称(如:有几个参数,在这里面就写几个参数名称,每个名称中间用分隔符分割,分隔符在下面的“Delimitet”中定义,为了和文件中的“,”对于,这里也用“,”分割每个参数名,(比如:use,password)

说明:这里的username与password为自己定义的名称,请求中要用这个名称,例如${参数名称}

Delimitet:定义分隔符,这里定义某个分隔符,则在“Variable Names”用这里定义的分隔符分割参数。CSV默认为英文的豆号

Recycle on EOF:是否循环读入,因为CSV Data Set Config一次读入一行,分割后存入若干变量中交给一个线程,如果线程数超过文本的记录行数,那么可以选择从头再次读入

设置CSV Data Set Config如下图所示:


 

当文本中参数运行完成后,再从第一个开始循环读取,如果选择为false,则停止运行

备注说明:这里我用通俗的语言大概讲一下Recycle on EOF与Stop thread on EOF结果的关联

Recycle on EOF :到了文件尾处,是否循环读取参数,选项:true和false

Stop thread on EOF:到了文件尾处,是否停止线程,选项:true和false

当Recycle on EOF 选择true时,Stop thread on EOF选择true和false无任何意义,通俗的讲,在前面控制了不停的循环读取,后面再来让stop或run没有任何意义

当Recycle on EOF 选择flase时,Stop thread on EOF选择true,线程4个,参数3个,那么只会请求3次

当Recycle on EOF 选择flase时,Stop thread on EOF选择flase,线程4个,参数3个,那么会请求4次,但第4次没有参数可取,不让循环,所以第4次请求错误


3.在需要使用变量的地方,比如在登录操作中,需要提交的表单字段包含用户名密码,我们就可以用${变量名}的形式进行替换,例如${user}和${password}

参数设置如图所示:

Allow quoted data?Should the CSV file allow values to be quoted? If enabled, then values can be enclosed in - double-quote - allowing values to contain a delimeter.


pasting

4. 最后,添加后,可以通过“添加-监视器-查看结果树(请求部分)”,来检验参数化是否成功,运行线程组,如果失败,那么检查一下文本的路径,变量大小写等等,手册上说使用相对文本路径时,要以测试配置文件(默认是jmeter的bin目录)的目录为参考,但是我试过似乎不行,换成绝对路径就可以了


备注说明:

1、使用这个元件做参数时,尽量用CSV格式的表格来做,我试过其它格式的dat和txt,都读取不到

2、这个元件要在该请求下单独添加










parameters


AttributeDescriptionRequired
NameDescriptive name for this element that is shown in the tree.No
Clear cache each iterationIf selected, then the cache is cleared at the start of the thread.Yes
Use Cache Control/Expires header when processing GET requestsSee description above.Yes
Max Number of elements in cacheSee description above.



ATTENTION:

现在对于JMeter来说,一个测试计划只能有一个cookie管理器。因为当多个magager存在时,JMeter目前还没有方法来指定使用那个manager。同时,一个cookie manager中的存储的cookie也不能被其他cookie manager所引用,所以同一个计划中不建议使用多个cookie manager

HTTP COOKIE Manager管理cookie有两种方法:
  1. 他可以像浏览器一样存储和发送cookie,如果你要发送一个带cookie的http请求,cookie manager会自动存储该请求的cookies,并且后面如果发送同源站点的http请求时,都可以用这个cookies。每个JMeter线程都有自己的“cookie存储区域”,
  所以当你测试一个使用cookie来管理session信息的web站点时,每个JMeter线程都有自己的session。
  注意:
以这种自动收集的方式收集到的cookie不会在cookie manager中进行展示,但是运行后,通过:查看结果树(监 听器)可以查看到cookie信息。
 早期的JMeter版本(2.3.2或更早)对与cookie的管理是支持跨域的,也就是说不同域名的网站都可以使用cookie manager中  的cookie,2.3.2版本之后,这个就不可以了,必须同源,才能共用cookie,如果你想让JMeter的cookie manager支持跨域,  修改JMeter.property :
CookieManager.check.cookies=false

  接受到的cookie会被自动存储在线程变量中,但是从Jmeter2.3.2版本后,默认不再存储,如果你想要manager自动存储收集到 的cookie,你需要修改JMeter.property :
CookieManager.save.cookies=true
    存储的时候,cookie的key会以“COOKIE_”为前缀命名(默认情况),如果你想自定义这个前缀,
修改JMeter.property :
CookieManager.name.prefix= 
    这个配置如果未启用(也就是维持默认),我们可以通过一下方式获取到cookie的值:${COOKIE_name},其       中name为cookie的名称

   2. 除了上面说的自动收集,我们还可以手动添加cookie,这里,笔者要给大家一个建议,尽量不要一个一个手动去填写,我们可  以结合firefox的插件firebug,直接将cookie导入,操作如下
  • 打开firebug,如图
JMeter——HTTP COOKIE Manager(cookie管理器) - 一切随缘 - 随缘
   点击红色框中的,下拉框中有个导出本站点的cookie,就可以将cookie信息保存为一个cookies.txt文件,接着打开jmeter 的cookie manager:
JMeter——HTTP COOKIE Manager(cookie管理器) - 一切随缘 - 随缘
  载入刚才导出的cookies.txt文件即可。
各个参数说明:
名称 描述 是否必填
  Name 自定义该cookie的描述,例如:tuan.qq.com的cookie N
  Clear Cookies each Iteration 每次线程组运行前,都会清楚cookie,但是如果是手动添加的cookie,不会被清除 N
  Cookie Policy 选择cookie的管理策略,建议选择compatibility,兼容性强 
  User-Defined Cookies 用户自定义cookie
 
  Add Button 。。。略过 

HTTP信息头管理器  信息头部


Parameters

AttributeDescriptionRequired
NameDescriptive name for this element that is shown in the tree.No
Name (Header)Name of the request header. Two common request headers you may want to experiment with are "User-Agent" and "Referer".No (You should have at least one, however)
ValueRequest header value.No (You should have at least one, however)
Add ButtonAdd an entry to the header table.N/A
Delete ButtonDelete the currently selected table entry.N/A
Load ButtonLoad a previously saved header table and add the entries to the existing header table entries.N/A
Save As ButtonSave the current header table to a file.

HTTP授权管理器

例如 授权 访问 tomcat 这里主要是让JMeter能够通过Tomcat的基本认证,获取数据,在“用户名”和“密码”中加入对应的值


AttributeDescriptionRequired
NameDescriptive name for this element that is shown in the tree.No
Clear auth on each iteration ?Used by Kerberos authentication. If checked, authentication will be done on each iteration of Main Thread Group loop even if it has already been done in a previous one. This is usually useful if each main thread group iteration represents behaviour of one Virtual User.Yes
Base URLA partial or complete URL that matches one or more HTTP Request URLs. As an example, say you specify a Base URL of "http://jmeter.apache.org/restricted/" with a username of "jmeter" and a password of "jmeter". If you send an HTTP request to the URL "http://jmeter.apache.org/restricted/ant/myPage.html", the Authorization Manager sends the login information for the user named, "jmeter".Yes
UsernameThe username to authorize.Yes
PasswordThe password for the user. (N.B. this is stored unencrypted in the test plan)Yes
DomainThe domain to use for NTLM.No
RealmThe realm to use for NTLM.No
MechanismType of authentication to perform. JMeter can perform different types of authentications based on used Http Samplers:
SamplerAuthentications
JavaBASIC
HttpClient 3.1BASIC, DIGEST
HttpClient 4BASIC, DIGEST and Kerberos



http 默认请求

一个HTTP请求有着许多的配置参数,下面将详细介绍:

名称:本属性用于标识一个取样器,建议使用一个有意义的名称。

注释:对于测试没有任何作用,仅用户记录用户可读的注释信息。

服务器名称或IP :HTTP请求发送的目标服务器名称或IP地址。

端口号:目标服务器的端口号,默认值为80 。

协议:向目标服务器发送HTTP请求时的协议,可以是http或者是https ,默认值为http 。

方法:发送HTTP请求的方法,可用方法包括GET、POST、HEAD、PUT、OPTIONS、TRACE、DELETE等。

Content encoding :内容的编码方式,默认值为iso8859

路径:目标URL路径(不包括服务器地址和端口)

自动重定向:如果选中该选项,当发送HTTP请求后得到的响应是302/301时,JMeter 自动重定向到新的页面。

Use keep Alive : 当该选项被选中时,jmeter 和目标服务器之间使用 Keep-Alive方式进行HTTP通信,默认选中。

Use multipart/from-data for HTTP POST :当发送HTTP POST 请求时,使用Use multipart/from-data方法发送,默认不选中。

同请求一起发送参数 : 在请求中发送URL参数,对于带参数的URL ,jmeter提供了一个简单的对参数化的方法。用户可以将URL中所有参数设置在本表中,表中的每一行是一个参数值对(对应RUL中的 名称1=值1)。

同请求一起发送文件:在请求中发送文件,通常,HTTP文件上传行为可以通过这种方式模拟。

从HTML文件获取所有有内含的资源:当该选项被选中时,jmeter在发出HTTP请求并获得响应的HTML文件内容后,还对该HTML进行Parse 并获取HTML中包含的所有资源(图片、flash等),默认不选中,如果用户只希望获取页面中的特定资源,可以在下方的Embedded URLs must match 文本框中填入需要下载的特定资源表达式,这样,只有能匹配指定正则表达式的URL指向资源会被下载。


Java请求默认值

可以使用该请求执行java文件

http://www.myexception.cn/internet/1218112.html
用jmeter测试java程序

最近在用jmeter进行性能测试,防止被忘记,把步骤写下。

 

场景:测试java程序

 

1、右击测试计划-> 添加 -> Threads(Users) -> 线程组

 

2、设置线程属性,用于并发请求。

   

      介绍:

 

      线程数: 5

      Ramp-Up Period(in seconds) : 1

      循环次数: 2

 

      含义:1秒种起动5个线程,每个线程循环调用2次java请求     

 

3、线程组右击 -> 添加 -> Sampler -> Java请求

 

       之前建立测试类:

     

package com.my.test;  import java.util.Random;  import org.apache.jmeter.protocol.java.sampler.AbstractJavaSamplerClient; import org.apache.jmeter.protocol.java.sampler.JavaSamplerContext; import org.apache.jmeter.samplers.SampleResult;  /**  * Hello world!  *  */ public class App  extends AbstractJavaSamplerClient{      	 	 	public static double computer(double a,double b){ 		return a * b / a * a; 	}  	@Override 	public SampleResult runTest(JavaSamplerContext arg0) { 		// TODO Auto-generated method stub 		SampleResult sr = new SampleResult(); 		sr.sampleStart(); 		 		Random random = new Random(); 		for(int i=0; i<10000; i++){ 			computer(random.nextDouble(),random.nextDouble()); 			 		} 		 		sr.setSuccessful(true); 		sr.sampleEnd(); 		return sr; 	}  	@Override 	public void setupTest(JavaSamplerContext context) { 		// TODO Auto-generated method stub 		super.setupTest(context); 	}  	@Override 	public void teardownTest(JavaSamplerContext context) { 		// TODO Auto-generated method stub 		super.teardownTest(context); 	} 	 	 }

 

   使用的jar包有:ApacheJMeter_java.jar ,ApacheJMeter_core.jar

   上述jar包在 %JMETER_HOME%/lib/ext/下

 

   将测试程序打成jar包,放在%JMETER_HOME%/lib/ext/下

 

   这里会自动识别出该类,选择。

 

4、线程组右击 -> 添加 -> 监听器 -> 用表格察看结果

 

     Ctrl + R,开始运行,

     Ctrl + E,清除历史结果



JDBC Connection Configuration

 

Database URL: jdbc:oracle:thin:@192.168.1.168:1521:ptoracl
JDBC Driver class: oracle.jdbc.driver.OracleDriver
Username: lianggzone
Password:lianggzone

  附注:
  Database URL 格式:jdbc:oracle:thin:@[IP地址]:[端口号]:[实例名]
  用户名、密码就是连接数据库的用户名和密码



Parameters

AttributeDescriptionRequired
NameDescriptive name for the connection configuration that is shown in the tree.No
Variable NameThe name of the variable the connection is tied to. Multiple connections can be used, each tied to a different variable, allowing JDBC Samplers to select the appropriate connection. Each name must be different. If there are two configuration elements using the same name, only one will be saved. JMeter versions after 2.3 log a message if a duplicate name is detected.Yes
Max Number of ConnectionsMaximum number of connections allowed in the pool. In most cases, set this to zero (0) . This means that each thread will get its own pool with a single connection in it, i.e. the connections are not shared betweeen threads. 
If you really want to use shared pooling (why?), then set the max count to the same as the number of threads to ensure threads don't wait on each other.
Yes
Pool timeoutPool throws an error if the timeout period is exceeded in the process of trying to retrieve a connectionYes
Idle Cleanup Interval (ms)This is used to specify how long idle connections will be maintained in the pool before being closed. For a complete explanation on how this works, see ResourceLimitingPool.trim() (Defaults to "60000", 1 minute)Yes
Auto CommitTurn auto commit on or off for the connections.Yes
Keep-aliveThe keep-alive is used enable a mechanism to monitor the health of connections. If a connection has not been used for Max Connection Age (ms) then before returning the connection from a call to getConnection(), the connection is first used to ping the database to make sure that it is still alive. Setting the age allows the 5 second age to be overridden. Validation Query will be used to test it.Yes
Max Connection Age (ms)Controls the age mentionned in "Keep-Alive" property. It means connections not used for more than Max Connection Age will be testedYes
Validation QueryA simple query used to determine if the database is still responding.Yes
Database URLJDBC Connection string for the database.Yes
JDBC Driver classFully qualified name of driver class. (Must be in JMeter's classpath - easiest to copy .jar file into JMeter's /lib directory).Yes
UsernameName of user to connect as.No
PasswordPassword to connect with. (N.B. this is stored unencrypted in the test plan)No


Keystore Configuration

Control Panel

Parameters

AttributeDescriptionRequired
NameDescriptive name for this element that is shown in the tree.No
PreloadWether or not to preload Keystore. Setting is to true is usually the best option.Yes
Variable name holding certificate aliasVariable name that will contain the alias to use for authentication by client certificate. Variable value will be filled from CSV Data Set for example. In the screenshot, "certificat_ssl" will also be a variable in CSV Data Set.False
Alias Start IndexThe index of the first key to use in Keystore, 0-based.Yes
Alias End IndexThe index of the last key to use in Keystore, 0-based. When using "Variable name holding certificate alias" ensure it is large enough so that all keys are loaded at startup.Yes
LDAP Extended Request Defaults  and  LDAP请求默认值

可以添加一个config element中的LDAP Request Defaults用于控制一些共享默认值.

There are two ways to create test cases for testing an LDAP Server.

  1. Inbuilt Test cases.
  2. User defined Test cases.

There are four test scenarios of testing LDAP. The tests are given below:

  1. Add Test
    1. Inbuilt test :

      This will add a pre-defined entry in the LDAP Server and calculate the execution time. After execution of the test, the created entry will be deleted from the LDAP Server.

    2. User defined test :

      This will add the entry in the LDAP Server. User has to enter all the attributes in the table.The entries are collected from the table to add. The execution time is calculated. The created entry will not be deleted after the test.

  2. Modify Test
    1. Inbuilt test :

      This will create a pre-defined entry first, then will modify the created entry in the LDAP Server.And calculate the execution time. After execution of the test, the created entry will be deleted from the LDAP Server.

    2. User defined test

      This will modify the entry in the LDAP Server. User has to enter all the attributes in the table. The entries are collected from the table to modify. The execution time is calculated. The entry will not be deleted from the LDAP Server.

  3. Search Test
    1. Inbuilt test :

      This will create the entry first, then will search if the attributes are available. It calculates the execution time of the search query. At the end of the execution,created entry will be deleted from the LDAP Server.

    2. User defined test

      This will search the user defined entry(Search filter) in the Search base (again, defined by the user). The entries should be available in the LDAP Server. The execution time is calculated.

  4. Delete Test
    1. Inbuilt test :

      This will create a pre-defined entry first, then it will be deleted from the LDAP Server. The execution time is calculated.

    2. User defined test

      This will delete the user-defined entry in the LDAP Server. The entries should be available in the LDAP Server. The execution time is calculated.
      有两种方法可以创建测试用例测试LDAP服务器。
      内置的测试用例。
      用户定义的测试用例。
      有四个测试场景的测试LDAP。给出了测试如下:
      添加测试
      内置的测试:
      这将添加一个预定义的条目在LDAP服务器和计算执行时间。执行测试后,创建的条目将被删除从LDAP服务器。
      用户定义的测试:
      这将在LDAP服务器中添加条目。用户必须输入表中所有的属性。从表中收集到的条目添加计算执行时间。创建的条目测试后将不会被删除。
      修改测试
      内置的测试:
      这将创建一个预定义的条目,然后将修改在LDAP服务器创建的条目。并计算执行时间。执行测试后,创建的条目将被删除从LDAP服务器。
      用户定义的测试
      这将修改LDAP服务器中的条目。用户必须输入表中所有的属性。从表中收集修改的条目。计算执行时间。条目不会从LDAP服务器中删除。
      搜索测试
      内置的测试:
      这将创建的条目,然后将搜索可用的属性。它计算搜索查询的执行时间。结束时执行,创建条目将被删除从LDAP服务器。
      用户定义的测试
      这将搜索用户定义的条目(搜索过滤器)在搜索基地(再一次,由用户定义的)。应该在LDAP服务器中可用的条目。计算执行时间。
      删除测试
      内置的测试:
      这将创建一个预定义的条目,然后它将从LDAP服务器中删除。计算执行时间。
      用户定义的测试
      这将删除用户定义的条目在LDAP服务器。应该在LDAP服务器中可用的条目。计算执行时间。

Parameters

AttributeDescriptionRequired
NameDescriptive name for this sampler that is shown in the tree.No
Server Name or IPDomain name or IP address of the LDAP server. JMeter assumes the LDAP server is listening on the default port(389).Yes
Portdefault port(389).Yes
root DNDN for the server to communicateYes
UsernameLDAP server username.Usually
PasswordLDAP server password. (N.B. this is stored unencrypted in the test plan)Usually
Entry DNthe name of the context to create or Modify; may not be empty Example: do you want to add cn=apache,ou=test you have to add in table name=cn, value=apacheYes
Deletethe name of the context to Delete; may not be emptyYes
Search basethe name of the context or object to searchYes
Search filterthe filter expression to use for the search; may not be nullYes
add testthis name, value pair to added in the given context objectYes
modify testthis name, value pair to add or modify in the given context object






jmeter random variable

Control Panel

Parameters

AttributeDescriptionRequired
NameDescriptive name for this element that is shown in the tree.Yes
Variable NameThe name of the variable in which to store the random string.Yes
Format StringThe java.text.DecimalFormat format string to be used. For example "000" which will generate numbers with at least 3 digits, or "USER_000" which will generate output of the form USER_nnn. If not specified, the default is to generate the number using Long.toString()No
Minimum ValueThe minimum value (long) of the generated random number.Yes
Maximum ValueThe maximum value (long) of the generated random number.Yes
Random SeedThe seed for the random number generator. Default is the current time in milliseconds. If you use the same seed value with Per Thread set to true, you will get the same value for earch Thread as per Random class.No
Per Thread(User)?If False, the generator is shared between all threads in the thread group. If True, then each thread has its own random generator.Yes

 


18.4.13 TCP Sampler Config

The TCP Sampler Config provides default data for the TCP Sampler

Control Panel

Parameters

AttributeDescriptionRequired
NameDescriptive name for this element that is shown in the tree.No
TCPClient classnameName of the TCPClient class. Defaults to the property tcp.handler, failing that TCPClientImpl.No
ServerName or IPName or IP of TCP serverNo
Port NumberPort to be usedNo
Re-use connectionIf selected, the connection is kept open. Otherwise it is closed when the data has been read.Yes
Close connectionIf selected, the connection will be closed after running the sampler.Yes
SO_LINGEREnable/disable SO_LINGER with the specified linger time in seconds when a socket is created. If you set "SO_LINGER" value as 0, you may prevent large numbers of sockets sitting around with a TIME_WAIT status.No
End of line(EOL) byte valueByte value for end of line, set this to a value outside the range -128 to +127 to skip eol checking. You may set this in jmeter.properties file as well with eolByte property. If you set this in TCP Sampler Config and in jmeter.properties file at the same time, the setting value in the TCP Sampler Config will be used.No
Connect TimeoutConnect Timeout (milliseconds, 0 disables).No
Response TimeoutResponse Timeout (milliseconds, 0 disables).No
Set NodelayShould the nodelay property be set?No
Text to SendText to be sent


Control Panel

 

If you have more than one Thread Group, make sure you use different names for different values, as UDVs are shared between Thread Groups. Also, the variables are not available for use until after the element has been processed, so you cannot reference variables that are defined in the same element. You can reference variables defined in earlier UDVs or on the Test Plan.

 

Parameters

AttributeDescriptionRequired
NameDescriptive name for this element that is shown in the tree.No
User Defined VariablesVariable name/value pairs. The string under the "Name" column is what you'll need to place inside the brackets in ${...} constructs to use the variables later on. The whole ${...} will then be replaced by the string in the "Value" column.No

 


18.4.10 Login Config Element

The Login Config Element lets you add or override username and password settings in samplers that use username and password as part of their setup.

Control Panel

Parameters

AttributeDescriptionRequired
NameDescriptive name for this element that is shown in the tree.No
UsernameThe default username to use.No
PasswordThe default password to use. (N.B. this is stored unencrypted in the test plan)No


18.4.17 Simple Config Element

The Simple Config Element lets you add or override arbitrary values in samplers. You can choose the name of the value and the value itself. Although some adventurous users might find a use for this element, it's here primarily for developers as a basic GUI that they can use while developing new JMeter components.

Control Panel

Parameters

AttributeDescriptionRequired
NameDescriptive name for this element that is shown in the tree.Yes
Parameter NameThe name of each parameter. These values are internal to JMeter's workings and are not generally documented. Only those familiar with the code will know these values.Yes
Parameter ValueThe value to apply to that parameter.

18.4.16 Counter

Allows the user to create a counter that can be referenced anywhere in the Thread Group. The counter config lets the user configure a starting point, a maximum, and the increment. The counter will loop from the start to the max, and then start over with the start, continuing on like that until the test is ended.

From version 2.1.2, the counter now uses a long to store the value, so the range is from -2^63 to 2^63-1.

Control Panel

Parameters

AttributeDescriptionRequired
NameDescriptive name for this element that is shown in the tree.No
StartThe starting number for the counter. The counter will equal this number during the first iteration.Yes
IncrementHow much to increment the counter by after each iteration.Yes
MaximumIf the counter exceeds the maximum, then it is reset to the Start value. For versions after 2.2 the default is Long.MAX_VALUE (previously it was 0).No
FormatOptional format, e.g. 000 will format as 001, 002 etc. This is passed to DecimalFormat, so any valid formats can be used. If there is a problem interpreting the format, then it is ignored. [The default format is generated using Long.toString()]No
Reference NameThis controls how you refer to this value in other elements. Syntax is as in user-defined values $(reference_name} .Yes
Track Counter Independently for each UserIn other words, is this a global counter, or does each user get their own counter? If unchecked, the counter is global (ie, user #1 will get value "1", and user #2 will get value "2" on the first iteration). If checked, each user has an independent counter.No
Reset counter on each Thread Group IterationThis option is only available when counter is tracked per User, if checked, counter will be reset to Start value on each Thread Group iteration. This can be useful when Counter is inside a Loop Controller.No

 


 评论这张
 

posted on 2014-02-28 13:49 顺其自然EVO 阅读(9572) 评论(0)  编辑  收藏 所属分类: jmeter and badboy


只有注册用户登录后才能发表评论。


网站导航:
 
<2014年2月>
2627282930311
2345678
9101112131415
16171819202122
2324252627281
2345678

导航

统计

常用链接

留言簿(54)

随笔分类

随笔档案

文章分类

文章档案

搜索

最新评论

阅读排行榜

评论排行榜