Run Spring Boot application on multiple server address - java

Just curious about this!!I have a spring boot application running on 10.0.0.1(9000 port) and same instance has a subnet for 10.0.0.2 The application is running on pid P1, How can I bind my Spring boot application to both the server address which must point to same process P1 and on same port 9000
10.0.0.1:9000/api
10.0.0.2:9000/api
The application must be accessible on both the server address without using create the new instance or new port,
I have tried using reverse proxy and proxy but still no luck,Is possible to do ?
https://access.redhat.com/solutions/873953 Looking something similar to this in Spring.

First way: find it on 0.0.0.0 which will then be available on all ip addresses.
Second way: Use a reverse proxy like nginx which listens on 10.0.0.2:9000 and forwards to your spring. (you mentioned it does not work. could you please give more details?)
Third way: let your spring listen on another port, say 8888. then use nginx to listen on both 10.0.0.1 and 10.0.0.2 and forward. Actually in production environment this is also very common (placing a reverse proxy before actual workload).

Related

How to setup eureka clients behind reverse proxy with different port?

I am currently trying to setup service discovery with eureka, but the clients register with the wrong port. Every Eureka client is on a different server behind its own nginx reverse proxy and it is reachable from outside via https on port 443, but the java eureka clients are configured on different port. I also tried configuring them on the same port as nginx exposes, but than the nginx server has infinited redirects and stops after some attempts with error "invalid redirect". Being on different port the eureka clients register at the server with the port configure in spring boot yaml server port config. If then a client tries to reach another client it uses the port configured in the spring boot application. I need to be able to register the eureka client on a different port than I am running the client. Is that possible? What am I missing here? Would be using Zuul as a gateway make a difference here?
Setup (every system is deployed on a different VServer behind NGINX reverse proxy):
Eureka Server
Multiple Eureka Clients (API, UI, etc)
Identity Management Keycloak SSO server not registered with eureka server
A port can only be used by one service at a time. Hence, you cannot configure nignx and spring boot to listen on the same port and receive the error message.
Spring boot does not know about the proxy setup and hence the eureka client registers the instance (with the spring.port) at the eureka server. You can configure the eurka instance with the EurekaInstanceConfig. In this case you want to change eureka.instance.port=443 to the one exposed by nginx.

How to specify the statsd client port?

I have one java spring boot application deployed on pcf environment. I have used statsd client library to send metrics to the statsd server. So the problem is how do I specify host and port in statsd client so that it can send metrics.
public StatsDClient statsDClient(
#Value("${metrics.statsd.host:localhost}") String host,
#Value("${metrics.statsd.port:8125}") int port,
#Value("${metrics.prefix:example.app}") String prefix
) {
return new NonBlockingStatsDClient(prefix, host, port);
}
I have to specify the host and port for the PCF deployed app, How to do it ?
If I am understanding it correctly you have two apps running in PCF.
One Spring boot app- which you are calling some client app.
Second is your statsd server
and you need to establish a communication between these two.
As Daniel mentioned in comment you have two ways to do it.
HTTP/TCP
Internal Route
Problem with option 1 is that you may not be able to use that with host and port separately as PCF internally doing that.
I'd recommended to use the second option- Internal route which gives you clear host name and port which you need to configure in client app.
Here are the steps you can follow to configure the Container-to-Container networking
Add a new route to your server app -i.e. app1.apps.internal
Create network policy with client and server app - link
Define property in config server or code-base whatever process you are using for property externalization - Your final URL would look like: app1.apps.internal:8080

CloudFoundry websocket failed: Establishing a tunnel via proxy server failed

Note: I am not using Pivotal CF.
I have a java application deployed on CloudFoundry. I am using embedded Jetty to host my Jersey REST API. This API is by default exposed on port 8080 by cloud foundry.
My application also needs some websockets to stream data to the browser. I am using Java-WebSocket (https://github.com/TooTallNate/Java-WebSocket) for this. On my local machine, I was using port 8887 for my websocket connection. Everything worked fine.
After deploying on CloudFoundry, I can access my REST API but not my websocket. After searching a bit online, I found that websocket connections are only allowed on port 4443 (http://docs.run.pivotal.io/release-notes/)
I changed my server side to reflect this
import org.java_websocket.server.WebSocketServer;
public class MyWebSocket extends WebSocketServer {
public MyWebSocket() throws UnknownHostException {
super(new InetSocketAddress(4443));
}
#Override
public void onOpen(org.java_websocket.WebSocket websocket, ClientHandshake handshake) {
// Handle this
}
}
On my client side, I am connecting the websocket using the following
wss://my_cf_app.com:4443/
But I am getting the following exception.
WebSocket connection to 'wss://my_cf_app.com:4443/' failed:
Establishing a tunnel via proxy server failed
I also tried to connect the websocket on server side using "PORT" environment variable of CF but I get "Address already in use" error in Java-WebSocket.
I have tried many different things but I am unable to figure this out. Any help would be awesome.
After deploying on CloudFoundry, I can access my REST API but not my websocket. After searching a bit online, I found that websocket connections are only allowed on port 4443 (http://docs.run.pivotal.io/release-notes/)
Port 4443 is specific to Pivotal Web Services (and some installs of CF that run on AWS). Most PCF installs do not have a separate port for WSS, but just use 443 along with the HTTPS traffic. The port used ultimately depends on the load balancer being used in front of the CF installation and what it supports.
You would never have your application listen on port 4443. Port 4443 is the external port for traffic where the load balancer listens. This traffic will be directed to the port assigned to your application, which is $PORT (env variable).
I also tried to connect the websocket on server side using "PORT" environment variable of CF but I get "Address already in use" error in Java-WebSocket.
This is the correct behavior, i.e. you should be listening on the port assigned through $PORT env variable. What the error is telling you is that something is already listening on this port and you cannot have two things listening on the same port.
There is only one port available per application at this time (likely to change in the future). For now, if you have two separate applications listening on two separate ports then you need to push them to CF as two separate applications.
What you can do to make them appear like one application to end users is to map each one to a specific path. See the --route-path argument of cf push or docs for cf create-route.
https://docs.cloudfoundry.org/devguide/deploy-apps/routes-domains.html#create-route

How configure aws-ec2 Instance to run playframework 1.2.7 application

I have deployed our playframework 1.2.7 web application to aws-ec2 ubuntu instance. The started the application on port 8081 since 80 or 8080 complains about not able to bind to those ports. How can I configure the ubuntu instance either througth the aws security group or on ubuntu itself so that I wouldn't have to add the port 8081 to the end of the public url or the public ip provided by aws.
ie I don't want do this:
example.com:8081 / ip4:8081
But I just want to use:
example.com / ip4
to access the application.
Please I need help on this.
The problem is that on Ubuntu ports < 1024 are privileged. This means that normal users can do nothing with it. To start play on port 80 you could simply start it as root user. Anyway it's not a best practice to start webserver as root due to possible security issues.
I'd suggest to start it on whatever non-privileged port you want, as normal user, and make use of an Elastic Load Balancer (ELB) to redirect all inbound traffic on port 80(or 443 for instance) to your play port. You can accomplish this simply using AWS web interface, when creating an ELB
So users will reach your play instance calling ELB on port 80 using Amazon auto-assigned dns name.
Example flow:
User browser --> http://your-elb-dns-name.com --> your_play_server_ip:8081
Just make sure that the Security Group associated to your play server instance will accept inbound traffic on 8081 from your ELB (you can identify your ELB using the amazon id assigned during its creation)
Another great advantage of using this ELB approach is that you can use it as reverse proxy to hide your ec2-instance(s) ip(s) to the internet. In fact, if you use ELB you could also avoid assignin a public ip to your ec2 instance during creation. ELB doesn't need to know a public ip beacuse it will have access to the Virtual Private Cloud (VPC) in which your ec2 instance was started
Another possible approach, if you don't want to use ELB, is to install NGINx or Apache on your ec2 instance to act as reverse proxy, but I think you should make use of Amazon web services to accomplish that. You may want to use an internal NGINX or Apache reverse proxy if you need to hide a particular resource of your play server to the internet.
https://aws.amazon.com/it/elasticloadbalancing/

Glassfish, EC2, Swing Application not connecting to #remote interface

I have Glassfish with an EAR deployed that includes a swing application that I run through Java Web Start which connects to my EJB through the #remote interface.
We have a server set up with a static IP and all I need to do is set /etc/hostname to my hostname (x.x.com) and in my /etc/hosts I have:
127.0.0.1 localhost
x.x.x.x x.x.com
Pretty simple. The application runs fine.
However, we want to migrate to EC2. I have a server up with Glassfish and everything is great. I have an Elastic IP pointed to it and my domain name pointed to that. All good.
The program downloads and updates fine also through Java Web Start.
The problem comes when trying to connect from my swing app to the server. It connects through CORBA, which I don't know much about.
I can't set the /etc/hosts file because the Elastic IP isn't the IP Address. Amazon assigns local addresses to the servers. I can't set /etc/hosts to one of those because if they were restarted it would change. And I don't want to edit it every time.
Does anyone know how to bypass this or fix it so Glassfish doesn't need it? It is killing me.
You should still be able to add an entry to your hosts file for your eIP - have you tried that?
EC2 instances all have a public IP and a private 10.X.X.X address. The eIP replaces the public IP address and is fixed (until you disassociate it).
The alternative with AWS, which will allow you to have a fixed private IP too, is to deploy to a VPC. Amazon have some very good documentation on VPCs.
What you're getting, in a nutshell, is comparable to a local network, so you can just pick your CIDR block and create subnets, for example 10.0.1.0/24. Now, when you launch an EC2 instance, you can launch into that VPC subnet and choose the private IP. Along with your eIP, you now have both IP addresses (public and private) set permanently, unless you decide to change them yourself (for whatever reason).
You can even add secondary IP addresses if you want.

Categories