关于ConnectionManager的配置(原)
Domain | IP | Description |
imserver.p2pvpn.com | 172.0.7.205 | 基于openfire的im server |
cm1.p2pvpn.com | 172.0.7.206 | Connection Manager |
cm2.p2pvon.com | 172.0.7.205 | Connection Manager |
dns | 172.0.7.206 | dns服务器 |
一.配置dns服务器(这里的dns仅用于内网测试)
1.db.p2pvpn.com文件,用于正向解析
代码
$TTL 604800
@ IN SOA dns.p2pvpn.com. root.p2pvpn.com. (
1
604800
86400
2419200
604800 )
@ IN NS dns
dns IN A 172.0.7.206
imserver IN A 172.0.7.205
cm IN A 172.0.7.206
cm IN A 172.0.7.205
2.db.7.0.172文件用于反向解析(可有可无,一般反向解析很少用)
代码
$TTL 604800
@ IN SOA dns.p2pvpn.com. root.p2pvpn.com. (
1
604800
86400
2419200
604800 )
@ IN NS dns
206 IN PTR dns
3.修改named.conf.local
zone "p2pvpn.com" {
type master;
file "/etc/bind/db.p2pvpn.com";
};
zone "7.0.172.in-addr.arpa" {
type master;
file "/etc/bind/db.7.0.172";
};
通过上面的配置, 只需要im client通过cm.p2pvpn.com这个domain就能轮询二台Connection Manager
dns配置注意:
sudo /etc/init.d/bind9 restart
sudo vim /etc/resolv.conf:指向本地dns.
二.配置Connection Manager
1.修改cm1的manager.xml
代码
<?xml version="1.0" encoding="UTF-8"?>
<!--
This file stores bootstrap properties needed by Connection Managers.
Property names must be in the format: "prop.name.is.blah=value"
That will be stored as:
<prop>
<name>
<is>
<blah>value</blah>
</is>
</name>
</prop>
-->
<!-- root element, all properties must be under this element -->
<jive>
<xmpp>
<!-- Name of the server to connect. This property is required. -->
<domain>imserver.p2pvpn.com</domain>
<!-- IP address or hostname of the XMPP server. If not defined then a DNS SRV lookup
of the domain will be performed. -->
<!-- <hostname></hostname> -->
<!-- TCP port to connect to the XMPP server on. -->
<port>5262</port>
<!-- Password to use to log into the server. This property is required. -->
<password>1qaz2wsx</password>
<manager>
<!-- Name of the connection manager that uniquely identifies this manager.
This property is optional. A random name is generated if none was defined. -->
<name>cm1</name>
<!-- Number of connections to establish to the server. -->
<connections>1</connections>
<!-- Number of threads for processing incoming server traffic per connection. -->
<incoming>
<threads>5</threads>
</incoming>
</manager>
<server>
<certificate>
<!-- Flag that indicates if certificates of the server should be validated. -->
<verify>false</verify>
<verify>
<!-- Flag that indicates if certificates chain should be validated. -->
<chain>true</chain>
<!-- Verify that the the last certificate in the chain was issued by
a third-party that we trust. -->
<root>true</root>
<!-- For every certificate in the chain, verify that the certificate
is valid at the current time. -->
<validity>true</validity>
</verify>
<!-- Flag that indicates if self-signed certificates are accepted. -->
<accept-selfsigned>false</accept-selfsigned>
</certificate>
</server>
<client>
<!-- Milliseconds a client connection has to be idle to be closed.
Default is 30 minutes. -->
<idle>1800000</idle>
</client>
<socket>
<default>
<active>false</active>
<!-- Default port to use for plain/TLS client connections. -->
<port>5222</port>
</default>
<ssl>
<active>false</active>
<!-- Default port to use for client connections using old SSL method. -->
<port>5223</port>
<storeType>jks</storeType>
<!-- <keystore></keystore>
<keypass></keypass>
<truststore></truststore>
<trustpass></trustpass> -->
</ssl>
<!-- Listen on a specific network interface. -->
<!-- <network>
<interface></interface>
</network> -->
<!-- Low level socket settings. Use this section to finetune sockets based on load. -->
<!-- Maximum number of outstanding connection requests is set. This can be considered a backlog
of requests waiting on the TCP/IP port for the listener to accept the request. -->
<backlog>50</backlog>
<buffer>
<!-- Hint the size of the underlying buffers used by the platform for incoming network I/O -->
<receive>-1</receive>
<!-- Hint the size of the underlying buffers used by the platform for outgoing network I/O -->
<send>-1</send>
</buffer>
<!-- Specifies a linger-on-close timeout. This option disables/enables immediate return
from a close() of a TCP Socket.-->
<linger>-1</linger>
<!-- This option causes packets to be flushed on to the network more frequently. If you are
streaming large amounts of data, there is no buffering and hence no delay.-->
<!-- <tcp-nodelay>false</tcp-nodelay> -->
</socket>
<processor>
<!-- Number of processors that will be listening for incoming traffic. The optimal number is related
to the number of CPUs. Each processor will run in its own thread. -->
<!-- <count>1</count> -->
<!-- Number of threads that will process incoming traffic detected by processors. Note that
threads will be shared among processors. -->
<!-- <threads>
<standard>16</standard>
<ssl>16</ssl>
</threads> -->
</processor>
<!-- Configure http binding. -->
<httpbind>
<enabled>true</enabled>
<port>
<plain>7071</plain>
<secure>7443</secure>
</port>
<!-- Script syntax allows BOSH to be used in environments where clients may be restricted to using a particular server -->
<scriptSyntax>
<enabled>true</enabled>
</scriptSyntax>
<client>
<requests>
<!-- Longest time (in seconds) to wait before responding to any request during the session -->
<!-- <wait></wait> -->
<!-- Maximum allowable seconds over which a client can send empty requests to the server -->
<polling>5</polling>
<!-- Limit number of simultaneous requests the client makes with the 'requests' attribute -->
<max>2</max>
</requests>
<!-- Seconds a session has to be idle to be closed -->
<idle>30</idle>
</client>
</httpbind>
</xmpp>
<!-- Configure debug logger. -->
<log>
<debug>
<enabled>false</enabled>
</debug>
</log>
</jive>
2.修改cm2的manager.xml
代码
<?xml version="1.0" encoding="UTF-8"?>
<!--
This file stores bootstrap properties needed by Connection Managers.
Property names must be in the format: "prop.name.is.blah=value"
That will be stored as:
<prop>
<name>
<is>
<blah>value</blah>
</is>
</name>
</prop>
-->
<!-- root element, all properties must be under this element -->
<jive>
<xmpp>
<!-- Name of the server to connect. This property is required. -->
<domain>imserver.p2pvpn.com</domain>
<!-- IP address or hostname of the XMPP server. If not defined then a DNS SRV lookup
of the domain will be performed. -->
<!-- <hostname></hostname> -->
<!-- TCP port to connect to the XMPP server on. -->
<port>5262</port>
<!-- Password to use to log into the server. This property is required. -->
<password>1qaz2wsx</password>
<manager>
<!-- Name of the connection manager that uniquely identifies this manager.
This property is optional. A random name is generated if none was defined. -->
<name>cm2</name>
<!-- Number of connections to establish to the server. -->
<connections>1</connections>
<!-- Number of threads for processing incoming server traffic per connection. -->
<incoming>
<threads>5</threads>
</incoming>
</manager>
<server>
<certificate>
<!-- Flag that indicates if certificates of the server should be validated. -->
<verify>false</verify>
<verify>
<!-- Flag that indicates if certificates chain should be validated. -->
<chain>true</chain>
<!-- Verify that the the last certificate in the chain was issued by
a third-party that we trust. -->
<root>true</root>
<!-- For every certificate in the chain, verify that the certificate
is valid at the current time. -->
<validity>true</validity>
</verify>
<!-- Flag that indicates if self-signed certificates are accepted. -->
<accept-selfsigned>false</accept-selfsigned>
</certificate>
</server>
<client>
<!-- Milliseconds a client connection has to be idle to be closed.
Default is 30 minutes. -->
<idle>1800000</idle>
</client>
<socket>
<default>
<active>false</active>
<!-- Default port to use for plain/TLS client connections. -->
<port>5222</port>
</default>
<ssl>
<active>false</active>
<!-- Default port to use for client connections using old SSL method. -->
<port>5223</port>
<storeType>jks</storeType>
<!-- <keystore></keystore>
<keypass></keypass>
<truststore></truststore>
<trustpass></trustpass> -->
</ssl>
<!-- Listen on a specific network interface. -->
<!-- <network>
<interface></interface>
</network> -->
<!-- Low level socket settings. Use this section to finetune sockets based on load. -->
<!-- Maximum number of outstanding connection requests is set. This can be considered a backlog
of requests waiting on the TCP/IP port for the listener to accept the request. -->
<backlog>50</backlog>
<buffer>
<!-- Hint the size of the underlying buffers used by the platform for incoming network I/O -->
<receive>-1</receive>
<!-- Hint the size of the underlying buffers used by the platform for outgoing network I/O -->
<send>-1</send>
</buffer>
<!-- Specifies a linger-on-close timeout. This option disables/enables immediate return
from a close() of a TCP Socket.-->
<linger>-1</linger>
<!-- This option causes packets to be flushed on to the network more frequently. If you are
streaming large amounts of data, there is no buffering and hence no delay.-->
<!-- <tcp-nodelay>false</tcp-nodelay> -->
</socket>
<processor>
<!-- Number of processors that will be listening for incoming traffic. The optimal number is related
to the number of CPUs. Each processor will run in its own thread. -->
<!-- <count>1</count> -->
<!-- Number of threads that will process incoming traffic detected by processors. Note that
threads will be shared among processors. -->
<!-- <threads>
<standard>16</standard>
<ssl>16</ssl>
</threads> -->
</processor>
<!-- Configure http binding. -->
<httpbind>
<enabled>true</enabled>
<port>
<plain>7071</plain>
<secure>7443</secure>
</port>
<!-- Script syntax allows BOSH to be used in environments where clients may be restricted to using a particular server -->
<scriptSyntax>
<enabled>true</enabled>
</scriptSyntax>
<client>
<requests>
<!-- Longest time (in seconds) to wait before responding to any request during the session -->
<!-- <wait></wait> -->
<!-- Maximum allowable seconds over which a client can send empty requests to the server -->
<polling>5</polling>
<!-- Limit number of simultaneous requests the client makes with the 'requests' attribute -->
<max>2</max>
</requests>
<!-- Seconds a session has to be idle to be closed -->
<idle>30</idle>
</client>
</httpbind>
</xmpp>
<!-- Configure debug logger. -->
<log>
<debug>
<enabled>false</enabled>
</debug>
</log>
</jive>
注意:
由于使用grinder进行bosh的测试.所以开放了端口7071(默认是7070,但是该端口在我的机器上被占用)
三.启动imserver.在管理控制台-server settings-connection managers里面可以看到已经有cm1,cm2连接到imserver上.
四.设置grinder
1.修改one2one.py文件.
代码
# The Grinder 3.0.1
# HTTP script recorded by TCPProxy at 09.Haz.2008 01:32:23
from net.grinder.script import Test
from net.grinder.script.Grinder import grinder
from net.grinder.plugin.http import HTTPPluginControl, HTTPRequest
from HTTPClient import NVPair, Codecs
from java.util import Random
from org.xml.sax import InputSource
from org.apache.xerces.parsers import DOMParser
# A shorter alias for the grinder.logger.output() method.
log = grinder.logger.output
connectionDefaults = HTTPPluginControl.getConnectionDefaults()
httpUtilities = HTTPPluginControl.getHTTPUtilities()
# To use a proxy server, uncomment the next line and set the host and port.
# connectionDefaults.setProxyServer("localhost", 8001)
# These definitions at the top level of the file are evaluated once,
# when the worker process is started.
connectionDefaults.defaultHeaders = \
( NVPair('User-Agent', 'Mozilla/5.0 (Windows; U; Windows NT 5.1; tr; rv:1.8.1.14) Gecko/20080404 Firefox/2.0.0.14'),
NVPair('Accept-Encoding', 'gzip,deflate'),
NVPair('Accept-Language', 'tr-TR,tr;q=0.8,en-us;q=0.5,en;q=0.3'),
NVPair('Accept-Charset', 'ISO-8859-9,utf-8;q=0.7,*;q=0.7'),
NVPair('Cache-Control', 'no-cache'),
NVPair('Accept', 'text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5'), )
agentID = int(grinder.properties["grinder.agentID"])
processID = int(grinder.processName.split("-").pop())
host = '172.0.7.206'
#为了使用dns的负载均衡,使用domain.
domain = 'cm.p2pvpn.com'
boshUrl = 'http://' + domain + ':7071/http-bind/'
boshWait = 1
userPrefix = 'user'
#numThreads = 1
#从配置文件里读取每个process下面启动多少个thread.而不是使用写死的值.
numThreads = int(grinder.properties["grinder.threads"])
# Create an HTTPRequest for each request, then replace the
# reference to the HTTPRequest with an instrumented version.
# You can access the unadorned instance using request101.__target__.
request101 = Test(101, 'Initiate a BOSH session').wrap(HTTPRequest(url=boshUrl))
request201 = Test(201, 'Authenticate').wrap(HTTPRequest(url=boshUrl))
request301 = Test(301, 'Bind resource').wrap(HTTPRequest(url=boshUrl))
request401 = Test(401, 'Request a session from the server').wrap(HTTPRequest(url=boshUrl))
request501 = Test(501, 'Get roster').wrap(HTTPRequest(url=boshUrl))
request601 = Test(601, 'Change presence').wrap(HTTPRequest(url=boshUrl))
request701 = Test(701, 'Send one to one message').wrap(HTTPRequest(url=boshUrl))
request801 = Test(801, 'Make an empty request to the server').wrap(HTTPRequest(url=boshUrl))
request901 = Test(901, 'Terminate the session').wrap(HTTPRequest(url=boshUrl))
class TestRunner:
"""A TestRunner instance is created for each worker thread."""
def __init__(self):
log("agentID %s, processID %s, threadID %s ,numThreads %s" % (agentID, processID, grinder.threadNumber,numThreads))
#agentID通过./startAgent.sh 0来指定.
self.userID = (agentID * 1000) + (processID * numThreads) + grinder.threadNumber
self.targetUserID = (agentID *1000) + (processID * numThreads) + (grinder.threadNumber + 1) % numThreads
log("userID %s, targetUserID %s" % (self.userID, self.targetUserID))
self.username = userPrefix + str(self.userID)
self.password = userPrefix + str(self.userID)
log("username %s, password %s" % (self.username, self.password))
self.targetUser = userPrefix + str(self.targetUserID)
self.sid = ""
self.rid = Random().nextInt(1000000)
self.inactivity = 0
def initSession(self):
result = request101.POST('',
'<body xmlns=\"http://jabber.org/protocol/httpbind\" rid=\"' + str(self.rid) + '\" content=\"text/xml; charset=utf-8\" to=\"' + domain + '\" secure=\"true\" wait=\"' + str(boshWait) + '\" ack=\"1\" hold=\"1\" xml:lang=\"en\" xmpp:version=\"1.0\" xmlns:xmpp=\"urn:xmpp:xbosh\" />',
( NVPair('Content-Type', 'text/plain; charset=utf-8'), ))
self.rid += 1
body = getXMLcontent(result)
self.sid = body.getAttribute('sid')
self.inactivity = int(body.getAttribute('inactivity'))
log("sid: %s, inactivity: %s" % (self.sid, self.inactivity))
log("getSession response: %s" % result.getText())
return result
def auth(self):
authtext = Codecs.base64Encode('%s\x00%s\x00%s' % (self.username + '@' + domain, self.username, self.password)).strip()
log("authtext: " + authtext)
#if authtext[-1] == '\n':
# authtext = authtext[:-1]
result = request201.POST('',
'<body xmlns=\"http://jabber.org/protocol/httpbind\" rid=\"' + str(self.rid) + '\" sid=\"' + self.sid + '\"><auth xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\" mechanism=\"PLAIN\">' + authtext + '</auth></body>',
( NVPair('Content-Type', 'text/plain; charset=utf-8'), ))
self.rid += 1
log("auth response: %s" % result.getText())
return result
def bind(self):
result = request301.POST('',
'<body xmlns=\"http://jabber.org/protocol/httpbind\" rid=\"' + str(self.rid) + '\" sid=\"' + self.sid + '\" xmpp:restart=\"true\" xmlns:xmpp=\"urn:xmpp:xbosh\" xml:lang=\"en\" to=\"' + domain + '\"><iq type=\"set\" id=\"bind_1\"><bind xmlns=\"urn:ietf:params:xml:ns:xmpp-bind\"><resource>Home</resource></bind></iq></body>',
( NVPair('Content-Type', 'text/plain; charset=utf-8'), ))
self.rid += 1
log("bind response: %s" % result.getText())
return result
def requestSession(self):
log("rid = " + str(self.rid))
result = request401.POST('',
'<body xmlns=\"http://jabber.org/protocol/httpbind\" rid=\"' + str(self.rid) + '\" sid=\"' + self.sid + '\"><iq type=\"set\" from=\"' + self.username + '@' + domain + '/Home\" to=\"' + domain + '\" id=\"session_2\"><session xmlns=\"urn:ietf:params:xml:ns:xmpp-session\" /></iq></body>',
( NVPair('Content-Type', 'text/plain; charset=utf-8'), ))
self.rid += 1
log("requestSession response: %s" % result.getText())
return result
def getRoster(self):
log("rid = " + str(self.rid))
result = request501.POST('',
'<body xmlns=\"http://jabber.org/protocol/httpbind\" rid=\"' + str(self.rid) + '\" sid=\"' + self.sid + '\"><iq type=\"get\" id=\"roster_3\"><query xmlns=\"jabber:iq:roster\" /></iq></body>',
( NVPair('Content-Type', 'text/plain; charset=utf-8'), ))
self.rid += 1
log("getRoster response: %s" % result.getText())
return result
def changePresence(self, show):
result = request601.POST('',
'<body xmlns=\"http://jabber.org/protocol/httpbind\" rid=\"' + str(self.rid) + '\" sid=\"' + self.sid + '\"><presence from=\"' + self.username + '@' + domain + '/Home\"><show>' + show + '</show></presence></body>',
( NVPair('Content-Type', 'text/plain; charset=utf-8'), ))
self.rid += 1
log("changePresence %s response: %s" % (show, result.getText()))
return result
def sendMessage(self, message, target):
result = request701.POST('',
'<body xmlns=\"http://jabber.org/protocol/httpbind\" rid=\"' + str(self.rid) + '\" sid=\"' + self.sid + '\"><message type=\"chat\" from=\"' + self.username + '@' + domain + '/Home\" to=\"' + target + '@' + domain + '\"><body>' + message + '</body></message></body>',
( NVPair('Content-Type', 'text/plain; charset=utf-8'), ))
self.rid += 1
log("sendMessage response: %s" % result.getText())
return result
def poll(self):
result = request801.POST('',
'<body xmlns=\"http://jabber.org/protocol/httpbind\" rid=\"' + str(self.rid) + '\" sid=\"' + self.sid + '\" />',
( NVPair('Content-Type', 'text/plain; charset=utf-8'), ))
self.rid += 1
log("poll response: %s" % result.getText())
return result
def terminate(self):
result = request901.POST('',
'<body xmlns=\"http://jabber.org/protocol/httpbind\" rid=\"' + str(self.rid) + '\" sid=\"' + self.sid + '\" type=\"terminate\"><presence type=\"unavailable\" from=\"' + self.username + '@' + domain + '/Home\" to=\"' + domain + '\" /></body>',
( NVPair('Content-Type', 'text/plain; charset=utf-8'), ))
self.rid += 1
log("terminate response: %s" % result.getText())
return result
def __call__(self):
"""This method is called for every run performed by the worker thread."""
self.initSession()
self.auth()
self.bind()
self.requestSession()
self.getRoster()
message = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Duis rutrum porttitor ante. Nunc arcu leo."
show = "chat"
#for i in range(2):
while(True):
if show == "dnd":
show = "chat"
else:
show = "dnd"
self.changePresence(show)
if grinder.statistics.forLastTest.time < 5000:
grinder.sleep(5000 - grinder.statistics.forLastTest.time)
for j in range(5):
self.sendMessage(message, self.targetUser)
if grinder.statistics.forLastTest.time < 5000:
grinder.sleep(5000 - grinder.statistics.forLastTest.time)
self.terminate()
def getXMLcontent(result):
parser = DOMParser()
parser.reset()
parser.parse(InputSource(result.inputStream))
root = parser.getDocument().getDocumentElement()
return root
def instrumentMethod(test, method_name, c=TestRunner):
"""Instrument a method with the given Test."""
unadorned = getattr(c, method_name)
import new
method = new.instancemethod(test.wrap(unadorned), None, c)
setattr(c, method_name, method)
# Replace each method with an instrumented version.
# You can call the unadorned method using self.getSession.__target__().
instrumentMethod(Test(100, 'Initiate a BOSH session'), 'initSession')
instrumentMethod(Test(200, 'Authenticate'), 'auth')
instrumentMethod(Test(300, 'Bind resource'), 'bind')
instrumentMethod(Test(400, 'Request a session from the server'), 'requestSession')
instrumentMethod(Test(500, 'Get roster'), 'getRoster')
instrumentMethod(Test(600, 'Change presence'), 'changePresence')
instrumentMethod(Test(700, 'Send one to one message'), 'sendMessage')
instrumentMethod(Test(800, 'Make an empty request to the server'), 'poll')
instrumentMethod(Test(900, 'Terminate the session'), 'terminate')
2.修改grinder.properties文件
代码
#每个agent启动10个进程
grinder.processes=10
#每个进程启动100个线程.
grinder.threads=100
#A Python object is callable if it defines a __call__ method. Each worker thread performs a number of runs of the test script, as configured by the property #grinder.runs. For each run, the worker thread calls its TestRunner; thus the __call__ method can be thought of as the definition of a run.
grinder.runs=1
#grinder.processIncrement=1
#grinder.processIncrementInterval=10000
#grinder.initialProcesses=1
#grinder.useConsole=false
grinder.consoleHost=172.0.7.206
grinder.consolePort=6372
grinder.logDirectory=../logs
grinder.numberOfOldLogs=0
#grinder.initialSleepTime=500
#grinder.sleepTimeFactor=0.01
#grinder.sleepTimeVariation=0.005
grinder.jvm.arguments=-Dpython.cachedir=../tmp
grinder.script=../tests/one2one.py
3.启动./startConsole.sh
4.启动./startAgent.sh 0