关于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

posted @ 2010-05-18 17:37  highriver  阅读(3163)  评论(0编辑  收藏  举报