On Thu, Dec 15, 2011 at 12:25 PM, Christopher Schultz <
ch...@christopherschultz.net> wrote:

> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
> Hernan,
>
> On 12/14/11 7:15 PM, hernan wrote:
> > On Wed, Dec 14, 2011 at 8:17 PM, Christopher Schultz <
> >> What makes this "external" "program" non-multithreaded? Is it
> >> actually not threadsafe?
> >>
> >> If you can't run it in the same process as Tomcat, then you'll
> >> have to either use Runtime.exec or some type of wrapper around it
> >> -- or have that process running completely separately (as a
> >> daemon) and connect to it via sockets. Anything else requires
> >> native code, which you definitely don't want.
> >
> > My external application is a java application that uses java
> > wrapper (using JNI) for GLPK (written in ANSI C)
> > (http://www.gnu.org/s/glpk/), and GLPK is not threadsafe. Yes, I
> > will consider those alternatives, executing a new process when I
> > receive the request (Runtime.exec) and a separated deamon receiving
> > requests launching those processes.
>
> So, you're already running native code, eh? Well, you have several
> options IMO:
>
> 1. Run the thing as a separate process, wrapped in Java. This requires
>   that you run Runtime.exec() and call the Java wrapper you have.
>   I'm not entirely sure why you'd bother with the Java wrapper if you
>   were going to call-out to a separate program, but it's an option.
>   See #2 for caveats.
>

As separate process, I thought a java "server" process with the
wrapper that receive requests, launch a new process an response with the
result. The servlet (thread) calls the process using some kind of
client/server mechanism implemented in java (may be sockets).



> 2. Run the thing as a separate process *directly*. That is, instead of
>   doing Runtime.exec("/path/to/java/wrapper"), you'd just do
>   Runtime.exec("/path/to/native/binary"). You'll get better performance
>   and will avoid the native code required to bridge from Java to
>   native, which is likely to improve stability.
>   On the other hand, Runtime.exec() is a monster, and you can deadlock
>   your thread(s) easily if you don't know what you are doing.
>   Runtime.exec() essentially requires 2 threads per call because you
>   have to monitor both stdout and stderr and consume them otherwise
>   you risk deadlock. You might want to use a wrapper library to improve
>   your chances.
>

I agree, just doing Runtime.exec(binary), the disadvantage with Runtime is
that I'll not use java classes to comunicate input/output of the process.


> 3. Run the thing in-process with Tomcat, but use some kind of service
>   that isolates and serializes access to the non-threadsafe library.
>   You can do this with a singleton (or something like it) that has
>   a synchronized "run-GLPK" method: that will restrict callers such
>   that only one of them can use the library at a time.
>   I highly recommend that you try to acquire a lock using a timeout
>   instead of just blindly calling a synchronized method otherwise
>   you might end up in a deadlock situation if the library (or your
>   code) stalls at some point.
>

I've run successfully using syncronized methods, but I have to handle
concurrent requests and I don't want to serialize them because the response
times may be very different between them and I don't want some user have to
wait a lot for a "simple" request.


>   Another caveat: running JNI within a server process has inherent
>   risks of crashing the native module (if there is a bug in DLPK or
>   in the native wrapper around it) which will bring-down your whole
>   Tomcat service: that's obviously bad.
>

This is the main concern for me. For that reason I prefeer run glpk in a
different os process. I see two big ways: serving each servlet request with
a different process or run a different process/es dedicated only to
glpk. The first way is what I have to learn, but it seems that tomcat does
not support. In the second, I have more job coordinating processes and
manipulating input/output.



> 4. As I suggested before, run GLPK as a daemon process and communicate
>   with it via sockets or whatever. Has anyone written a GLPK-service?
>
> So, perhaps the simplest thing to do is #3, but it has the most
> runtime risks. The safest thing is to run as a separate process and
> communicate via sockets, but that might require significant investment
> in infrastructure (to build the service, then call-out to it).
>
> Are there any other requirements? For example: do you need to be able
> to handle multiple simultaneous incoming HTTP requests that all need
> to use GLPK? Or, is this relatively rare? If you need high
> concurrency, then option #3 simply isn't going to work unless the
> operations are very fast (which I suspect they are not).
>
> Do you have any idea how stable GLPK is? How about the native wrapper
> in Java?


In my experience GLPK is stable, and I've been doing some (serialized)
tests on java wrapper and they run successfully. But I'm not 99% sure that
will be perfect, and mainly I don't trust in the
program/programmer (me) that uses the library. I don't want that tomcat
crash due to some request.


> > Can I configure tomcat for running a new (or different) process for
> > each request?
>

> No. Tomcat runs in a single JVM, pretty much by definition. You can
> get Tomcat to run a *servlet* as a new instance of the class that
> defines it (by using SingleThreadModel) but that does not help you,
> here, and is a deprecated capability anyway.


Ok


> > or I have to run Apache HTTP Server and connect it to Tomcat?
>
> That's not necessary, either, although it might make it easier to wrap
> a service around GLPK with a simple set of CGI-BIN-style scripts
> written in Bash, Perl, etc.


Ok


> > If I have to run Apache HTTP Server which mechanism do I have to
> > connect it with tomcat? using Jk connector is the standard way?
>
> If you have to add httpd to the mix, you basically have 3 choices:
>
> 1. mod_proxy_http (uses HTTP protocol, comes bundled with httpd)
> 2. mod_proxy_ajp  (uses AJP protocol, comes bundled with httpd)
> 3. mod_jk         (uses AJP, you must build this separately)
>
> Although mod_jk does not ship with httpd, it has more flexible
> features and tends to be more up-to-date because it has releases that
> aren't tied to httpd's schedule.
>
> > Do you recommend me to read
> > http://tomcat.apache.org/connectors-doc/reference/apache.html ?
> > I've found also
> > http://tomcat.apache.org/connectors-doc/reference/apache.html but
> > it seems to be outdated.
>
> Those are the same URLs and I believe it is up-to-date. I would only
> read this if you have chosen to use httpd with mod_jk: that's what the
> documentation is for. If you want to use mod_proxy_*, you should read
> the documentation for httpd here:
> http://httpd.apache.org/docs/2.2/mod/mod_proxy_http.html
> or
> http://httpd.apache.org/docs/2.2/mod/mod_proxy_ajp.html
>
> I really think you need to decide (or tell us) what your requirements
> are before you start charging-into a decision like adding a completely
> new component to your environment.
>
>
Connecting apache htttpd server with tomcat, can I run several tomcat
instances and run each http request in a different tomcat instance? I know
that this is not the tomcat philosophy, but I just want to know if it is
possible or is common this approach for this kind of situations.

My principal requirements are: stability (main concern), scalability,
serving concurrent requests (no more than 100 concurrent requests).
If possible: flexibility/maintainability.

I think that your option #4 is the appropriate in this situation.


Thanks a lot for your comments and suggestions!!


Regards,
HernĂ¡n

Reply via email to