One of the biggest mistakes that many developers make when approaching web services is defining operations and messages that are too fine-grained. By doing so, developers usually define more than they really need. You need to ensure that your web service is coarse-grained and that the messages being defined are business oriented and not programmer's oriented.
The reason why top-down webservices are the pure web services is really this: you define at first the business and then the programming interface.
Don't define a web service operation for every Java method you want to expose. Rather, you should define an operation for each action you need to expose.
01.
public
void
checkInventory(
long
itemId) {
02.
InventoryDAO.checkInventory(itemId);
03.
}
04.
public
void
checkAccount(
long
itemId) {
05.
CustomerDAO.checkAccount(clientId);
06.
}
07.
public
void
saveOrder(
long
itemId,
long
clientId) {
08.
OrderDAO.persisteOrder(itemId,clientId);
09.
}
and this is a coarse grained web service:
1.
public
void
makeOrder(
long
itemId,
long
clientId) {
2.
InventoryDAO.checkInventory(itemId);
3.
CustomerDAO.checkAccount(clientId);
4.
OrderDAO.persisteOrder(itemId,clientId);
5.
}
for the sake of simplicity we don't have added any transaction commit/rollback however what we want to stress is that the first kind of web service is a bad design practice at first and then also will yield poor performance because of 3 round trips to the server carrying SOAP packets.
Web services have been defined from the grounds up to be interoperable components. That is you can return both primitive types and Objects. How do a C# client is able to retrieve a Java type returned by a Web Service or viceversa ? that's possible because the Objects moving from/to the Webservices are flattened into XML.
As you can imagine the size of the Object which is the parameter or the returntype has a huge impact on the performance. Be careful with Objects which contain large Collections as fields- they are usually responsible of web services bad performance. If you have collections or fields which are not useful in your response mark them as transient fields.
Evaluate carefully how much data your need to return
Consider returning only subsets of data if the Database queries are fast but the graph of Object is fairly complex. Example:
01.
@PersistenceContext
(unitName =
"persistenceUnit"
)
02.
private
EntityManager em;
03.
04.
@WebMethod
05.
public
List readTaskListByPage(
@WebParam
(name =
"start"
)
06.
int
start,
07.
@WebParam
(name =
"stop"
)
08.
int
stop) {
09.
10.
Query dbQuery = em.createQuery(query);
11.
12.
List listObjects = dbQuery.setFirstResult(start)
13.
.setMaxResults(stop-start).getResultList();
14.
15.
return
listObjects;
16.
17.
}
On the other hand if your bottleneck is the Database Connectivity reduce the trips to the Service and try to return as much data as possible.
Examine the SOAP packet
This tip is the logic continuation of the previous one: if you are dealing with complex Object types always check what is actually moving around the network. There are many ways to sniff a SOAP packet, from a tcp-proxy software which analyze the packets between two destinations. For example Apache delivers a simple tcp-monitoring utility which can be used for this purpose :
http://ws.apache.org/commons/tcpmon/
Here's how to debug SOAP messages with jboss:
http://www.mastertheboss.com/en/jboss-howto/49-jboss-http/178-how-to-monitor-webservices-soap-messages-.html
Cache on the client when possible
If your client application requests the same information repeatedly from the server, you'll eventually realize the server's performance, and consequently your application's response time, is not fast enough.
Depending on the frequency of the messaging and the type of data, it could be necessary to cache data on the client.
This approach however needs to address one important issue: how do we know that the data we are requesting is consistent ? the technical solution to this is inverting the order of elements: when the Data in our RDBMS has become inconsistent a Notification needs to be issued so that the Client cache is refreshed. In this article you'll find an elegant approach to this topic.
http://www.javaworld.com/javaworld/jw-03-2002/jw-0308-soap.html?page=2
Evaluate asynchronous messaging model
In some situations, responses to Web service requests are not provided immediately, but rather sometime after the initial request transactions complete. This might be due to the fact that the transport is slow and/or unreliable, or the processing is complex and/or long-running. In this situation you should consider an asynchronous messaging model.
The new WebService framework, JAX-WS, supports two models for asynchronous request-response messaging: polling and callback. Polling enables client code to repeatedly check a response object to determine whether a response has been received. Alternatively, the callback approach defines a handler that processes the response asynchronously when it is available.
Consider using asynchronous Web methods is particularly useful if you perform I/O-bound operations such as:
In the this article I showed how to achieve asynchronous web services using JAX-WS 2.0
http://www.mastertheboss.com/en/web-interfaces/111-asynchronous-web-services-with-jboss-ws.html
Use JAX-WS web services
The Webservices based on JAX-WS perform much better then JAX-RPC earlier Web services.
This is due to the fact that JAX-WS use JAXB for data type marshalling/unmarshalling which has a significant performance advantage over DOM based parsers.
For a detailed comparison benchmark check here:
http://java.sun.com/developer/technicalArticles/WebServices/high_performance/
Do you need RESTful web services ?
RESTful web services are stateless client-server architecture in which the web services are viewed as resources and can be identified by their URLs.
REST as a protocol does not define any form of message envelope, while SOAP does have this standard. So at first you don't have the overhead of headers and additional layers of SOAP elements on the XML payload. That's not a big thing, even if for limited-profile devices such as PDAs and mobile phones it can make a difference.
However the real performance difference does not rely on wire speed but with cachability. REST suggests using the web's semantics instead of trying to tunnel over it via XML, so RESTful web services are generally designed to correctly use cache headers, so they work well with the web's standard infrastructure like caching proxies and even local browser caches.
RESTFUL web services are not a silver bullet, they are adviced in these kind of scenarios:
REST web services are a good choices when your web services are completely stateless.Since there is no formal way to describe the web services interface, it's required that the service producer and service consumer have a mutual understanding of the context and content being passed along.
On the other hand a SOAP-based design may be appropriate when a formal contract must be established to describe the interface that the web service offers. The Web Services Description Language (WSDL) describes the details such as messages, operations, bindings, and location of the web service. Another scenario where it's mandatory to use SOAP based web services is an architecture that needs to handle asynchronous processing and invocation.
Eager initialization
JBossWS may perform differently during the first method invocation of each service and the following ones when huge wsdl contracts (with hundreds of imported xml schemas) are referenced. This is due to a bunch of operations performed internally during the first invocation whose resulting data is then cached and reused during the following ones. While this is usually not a problem, you might be interested in having almost the same performance on each invocation. This can be achieved setting the org.jboss.ws.eagerInitializeJAXBContextCache system property to true, both on server side (in the JBoss start script) and on client side (a convenient constant is available in org.jboss.ws.Constants). The JAXBContext creation is usually responsible for most of the time required by the stack during the first invocation; this feature makes JBossWS try to eagerly create and cache the JAXB contexts before the first invocation is handled.
Use Literal Message Encoding for Parameter Formatting
The encoded formatting of the parameters in messages creates larger messages than literal message encoding (literal message encoding is the default). In general, you should use literal format unless you are forced to switch to SOAP encoding for interoperability with a Web services platform that does not support the literal format. Here's an example of an RPC/encoded SOAP message for helloWorld
1.
<
soap:envelope
>
2.
<
soap:body
>
3.
<
helloWorld
>
4.
<
a
xsi:type
=
"xsd:string"
>George</
a
>
5.
<
b
xsi:type
=
"xsd:string"
>Michael</
b
>
6.
</
helloWorld
>
7.
</
soap:body
>
8.
</
soap:envelope
>
Here the operation name appears in the message, so the receiver has an easy time dispatching this message to the implementation of the operation.The type encoding info (such as xsi:type="xsd:int") is usually just overhead which degrades throughput performance. And this is the equivalent Document/literal wrapped SOAP message :
1.
<
soap:envelope
>
2.
<
soap:body
>
3.
<
helloWorld
> <
a
>George</
a
> <
b
>Michael</
b
></
helloWorld
>
4.
</
soap:body
>
5.
</
soap:enve
阅读全文……