Can I make a Java HttpServer threaded/process requests in parallel? - java

I have built a simple HttpServer following tutorials i have found online, using Sun's lightweight HttpServer.
Basically the main function looks like this:
public static void main(String[] args) throws Exception {
HttpServer server = HttpServer.create(new InetSocketAddress(8000), 0);
//Create the context for the server.
server.createContext("/", new BaseHandler());
server.setExecutor(null); // creates a default executor
server.start();
}
And I have implemented the BaseHandler Interface's method to process the Http request and return a response.
static class BaseHandler implements HttpHandler {
//Handler method
public void handle(HttpExchange t) throws IOException {
//Implementation of http request processing
//Read the request, get the parameters and print them
//in the console, then build a response and send it back.
}
}
I have also created a Client that sends multiple requests via threads. Each thread sends the following request to the server:
http://localhost:8000/[context]?int="+threadID
On Each client run, The requests seem to arrive in different order to the server, but they are served in a serial manner.
What i wish to acomplish is for the requests to be processed in a parallel manner if that is possible.
Is it possible, for example, to run each handler in a seperate thread, and if so, is it a good thing to do.
Or should i just drop using Sun's lightweight server altogether and focus an building something from scratch?
Thanks for any help.

As you can see in ServerImpl, the default executor just "run" the task :
157 private static class DefaultExecutor implements Executor {
158 public void execute (Runnable task) {
159 task.run();
160 }
161 }
you must provide a real executor for your httpServer, like that :
server.setExecutor(java.util.concurrent.Executors.newCachedThreadPool());
and your server will run in parallel.
Carefull, this is a non-limited Executor, see Executors.newFixedThreadPool to limit the number of Thread.

You used server.setExecutor(null) that runs the handler in the same caller thread. In this case, the main thread which runs the server.
You only need to change the line as
public static void main(String[] args) throws Exception {
HttpServer server = HttpServer.create(new InetSocketAddress(8000), 0);
//Create the context for the server.
server.createContext("/", new BaseHandler());
server.setExecutor(Executors.newCachedThreadPool());
server.start();
}

Related

Vertx http server only creating one instance

I am creating a simple micro service using vertx and when i start my server it only create one event thread when available is 12.
My code to start server is
public static void main(String[] args) {
Vertx vertx = Vertx.vertx();
int processorCounts = Runtime.getRuntime().availableProcessors();
DeploymentOptions options = new DeploymentOptions().setInstances(processorCounts);
vertx.deployVerticle( HttpRouter.class.getName(),options);
}
And my http router looks like this
#Override
public void start() throws Exception {
super.start();
Router router = Router.router(vertx);
router.get("/").handler(event -> {
event.response().end("Hello World");
});
vertx.createHttpServer().requestHandler(router::accept).listen(8001);
}
What is your process for testing? I assume you opened a browser and hit refresh on the same page. Then yes, the same verticle instance will handle the requests. The reason is Vert.x load balances connections among verticles instances, not requests.
Open a different browser and you should see different event loop names.

java: identify the actual http connection

I'm developing a HTTP server using HttpServer class. The code is like the following.
public static void main(String[] args) throws Exception {
HttpServer server = HttpServer.create(new InetSocketAddress(8989), 0);
server.createContext("/", new MyHandler());
server.setExecutor(null); // creates a default executor
server.start();
}
static class MyHandler implements HttpHandler {
public void handle(HttpExchange httpExchange) throws IOException {
/*
Some code here
*/
}
}
What I want is to find something (an id variable or an object) that identifyies the actual connection in the handler function.
If I make a break-point in the handler, I debug the server, then I run a client, I can see the content of httpExchange:
I think that connection attribute is a good choice. But I can't find how to get it from httpExchange, or its id.
Is there any suggestion?

Jar with multiple main

In one package I have two different classes Client.java and Server.java
I want to make this package jar, i mean executable.
First I want the Server class to run and after 2-3 seconds I want Client method to run. Is it possible?
Thank you
You have to leave only one main method and run your server and client in separate threads from it.
To do it, take a look at Runnable interface. Your server class and client class should implement it. Then you have to move the logic, used to start server and client to it's run() method.
class Server implements Runnable {
#Override
public void run() {
//your server starting logic here
}
}
class Client implements Runnable {
#Override
public void run() {
//your client starting logic here
}
}
After that, you can modify your main method, to start server and client, like:
public static void main(String args[]) throws InterruptedException {
Server server = new Server();
Client client = new Client();
Thread tServer = new Thread(server);
tServer.start();
//here you can wait some time to Server started
Thread tClient = new Thread(client);
tClient.start();
}

Aperiodically trigger a thread to run in Java

My server aperiodically receives join requests from new clients. Upon receiving a new join request, the server runs a service that can be finished real quick. I implement the service as a Java class (called JC) implementing the Runnable interface. I have parameters within the JC class.
At the caller side, I like to have only one instance (or static) of the JC. My question is how to trigger the run() method in the JC every time. Please show me some code. Thanks.
Hope following edits make sense, which is my current implementation.
In the Server that wants to trigger thread executing:
public class Server {
private static RealService mm = new RealService();
private static void update(){
new Thread(mm).start();
}
}
In the Service class:
public class RealService implements Runnable{
#Override
public void run() {
// TODO Auto-generated method stub
// Do something
}
}
You're question is not really clear here, but I would suggest reading about TimerTask in Java
You could use a socket to listen for incoming requests, the server can spawn a new thread each time there is a request. Once the thread completes, you should intimate the client.
You could read about how a concurrent server works.

Best way to send continuous data in Java using Netty

I'm planning to use Netty to design a TCP Server. When the client connects, I have to immediately start pumping
XML data to the client continuously...for hours/days. Its that simple.
So, I override "channelConnected" method and send data from that method, right?...thats great.
I will be using the following ChannelFactory
ChannelFactory factory =
new NioServerSocketChannelFactory(
Executors.newCachedThreadPool(),
Executors.newCachedThreadPool());
NioServerSocketChannelFactory documentation says
A worker thread performs non-blocking read and write for one or more Channels in a non-blocking mode.
Good.
According to effective Java Item 51: Don't depend on the thread scheduler, I want the worker thread to do a "unit of work" and then finish/return.
So in my case, though I have to send data continuously, I want to send some chunk (lets say 1 MB) and then be done (unit of work completed), so that worker thread can return. Then I'll send another 1 MB.
Below example is from the official guide of Netty HERE.
I guess the question is then, in this scenario, if i had to unconditionally keep sending time to the client, how would I do it, considering
each send as a unit of work.
One way of doing it would be to just put a while loop and do a Thread.Sleep. Any other way?
package org.jboss.netty.example.time;
public class TimeServerHandler extends SimpleChannelHandler {
#Override
public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) {
Channel ch = e.getChannel();
ChannelBuffer time = ChannelBuffers.buffer(4);
time.writeInt(System.currentTimeMillis() / 1000);
ChannelFuture f = ch.write(time);
f.addListener(new ChannelFutureListener() {
public void operationComplete(ChannelFuture future) {
Channel ch = future.getChannel();
ch.close();
}
});
}
#Override
public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) {
e.getCause().printStackTrace();
e.getChannel().close();
}
}
Doing a while/sleep would work, but would not be in the Netty super-scalable style. It would be thread-per-connection programming.
Instead, schedule a periodic job on an Executor that writes a message to the channel.

Categories