App service fabric not starting - azure

I keep getting errors related to conflicting ports. When I set a breakpoint inside Program.cs at the line containing
ServiceRuntime.RegisterServiceAsync
It actually stops there more then once per service in the service fabric project which is obviously why it's trying to bind to the same port more than once! Why is it doing this all of a sudden?!
HttpListenerException: Failed to listen on prefix 'https://+:446/' because it conflicts with an existing registration on the machine.

The problem is that the httplistener is trying to bind to a port that is already in use. The cause of this problem can be one of the following.
Another process is already using the port. Try netstat -ano to find out the process that is using the port and then tasklist /fi "pid eq <pid of process>" to find the process name.
Maybe you are starting your development cluster as a multi node instance. That way several nodes on one machine are trying to access the same port.
Maybe you have a frontend and an api that you want to run on the same port then you have to use the path-based binding capabilities of http.sys (If you are using the WebListener)
If this fails could you please post a snippet of the ServiceManifest.xml.
There should be a line defining your endpoint <Endpoint Protocol="https" Type="Input" Port="446" />

In your application manifest, you define how many instances of your service you want, the common mistake people do is to set this number to more than 1, and it will fail, because your local cluster show 5 nodes, but they all run on same machine, and the machine port will be used only in the first instance started.
Set the number of instances to 1 and you won't see multiple entrance on main entry-point at program.cs.
Make it configurable from ApplicationParameters, so you can define these number per environment.

You say that you didn't have to set the instance count before and that could be because you have the option to use Publish profiles that can differ from Cloud vs Local deployment. The profile will point to the corresponding Application Parameters file in which you can set the instance count to 1 for local deployments.
Perhaps something happened to your publish profiles?
ApplicationParameters/Local.1Node.xml:

Related

Scaling nodejs app while assigning unique ports

I'm trying to scale my game servers (nodejs) where instances should have unique ports assigned to them and where instances are separate (no load balancing of any kind) and are aware what port is assigned to them (ideally by env variable?).
I've tried using docker swarm but it has no option to specify port range and I couldn't find any way to allocate or to pass the allocated port to the instance so it's aware of the port its running on e.g via env variable.
Ideal solution would look like:
Instance 1: hostIP:1000
Instance 2: hostIP:1001
Instance 3: hostIP:1002
... etc
Now, I've managed to make this work by using regular Docker (non-swarm) by binding to host network and passing env variable PORT, but this way I'd have to manually spin up as many game servers as I'd need.
My node app uses "process.env.PORT" to bind to host's IP address:port
Any opinion on what solutions I could use to scale my app?
You could try different approaches.
Use docker compose and external service for extracting data from docker.sock as suggested here How to get docker mapped ports from node.js application?
Use redis or any key-value storage service to store port information and get it with every new instance launch. The most simple solution is to use redis incr command to get next free number but it has some limitations
Not To Sure What You Mean There? Could You Provide More Detail?

linux redirect localhost port to url port

I need to redirect localhost:8080 to http://url:8080/.
Some background:
I am using docker swarm stack services. One service (MAPS) creates a simple http server that lists xml files to port 8080 and another service (WAS) uses WebSphere Application Server that has a connector that uses these files, to be more precise it calls upon a file maps.xml that has the urls of the other files as http://localhost:8080/<file-name>.xml.
I know docker allows me to call on the service name and port within the services, thus I can use curl http://MAPS:8080/ from inside my WAS service and it outputs my list of xml files.
However, this will not always be true. The prod team may change the port number they want to publish or they might update the maps.xml file and forget to change localhost:8080 to MAPS:8080.
Is there a way to make it so any call to localhost:8080 gets redirected to another url, preferrably using a configuration file? I also need it to be lightweight since the WAS service is already quite heavy and I can't make it too large to deploy.
Solutions I tried:
iptables: Installed it on the WAS service container but when I tried using it it said my kernel was outdated
tinyproxy: Tried setting it up as a reverse proxy but I couldn't make it work
ncat with inetd: Tried to use this solution but it also didn't work
I am NO expert so please excuse any noob mistakes I made. And thanks in advance!
It is generally not a good idea to redirect localhost to another location as it might disrupt your local environment in surprising ways. Many packages depend on localhost being localhost :-)
it is possible to add MAPS to your hosts file (/etc/hosts) giving it the address of maps.

Riak "Node is not reachable"

I am using Riak 2.1.4 series in amazon. Totally new to it and have a couple of questions :
I deployed an instance of Riak. Its deployed in EC2 instance ?
Do we really need app.config and vm.args files for Riak configuration. I think if the nodename is available in Riak.conf thats enough isnt it ?
I see the IP address of the instance is different than the once configured in riak.conf is that fine ? i.e nodename for example instance name is ec2-35-160-XXX-XX.us-west-2.compute.amazonaws.com and riak.conf has riak#172.31.XX.XX
Only change in Riak.conf
ring_size = 64
erlang.distribution.port_range.minimum = 6000
erlang.distribution.port_range.maximum = 7999
transfer_limit = 2
search = on
This configuration exists in each instance. Am I missing something here ? How can I set this up for a five-node cluster?
I deployed an instance of Riak. Its deployed in EC2 instance ?
Not sure what you are asking here
Do we really need app.config and vm.args files for Riak configuration. I think if the nodename is available in Riak.conf thats
enough isnt it ?
The 'app.config' and 'vm.args' files are the old way to configure Riak. The 'riak.conf' and 'advanced.config' files are the new way. The old way is still accepted, probably to support legacy installations, but I would expect support for it to be dropped in a future release. See http://docs.basho.com/riak/kv/2.1.4/configuring/basic/
I see the IP address of the instance is different than the once configured in riak.conf is that fine ? i.e nodename for example
instance name is ec2-35-160-XXX-XX.us-west-2.compute.amazonaws.com and
riak.conf has riak#172.31.XX.XX
In general, if you want Erlang nodes to communicate they must be able to locate each other using the node name. The node name uses the local#domain pattern. All other nodes must be able to resolve the domain part to an IP address that is valid for the machine the node is running on, and the node itself will register the local part with the local erlang port mapper daemon(EPMD).
So whether or not riak#172.31.x.x is a valid node name will depend on your cluster's other nodes' ability to reach that private address.
Most riak-admin commands spawn a second maintenance node locally, which then uses remote procedure calls to talk to the running Riak instance. So if that 172.31.x.x IP address is not actually assigned to the local machine, those riak-admin commands will fail to find a node to talk to.

How do you connect REDHAWK devices on different machines?

I am trying to run a waveform with components operating on distinct machines. That is, I want A->B where component A runs on the GPP on machine 1 and component B runs on the GPP on machine 2. The CORBA nameserver on system A is visible in REDHAWK on system B, but I cannot access remote devices or components when I run a waveform.
How can I make the devices on one machine available to REDHAWK running on another?
Thanx for your assistance!
-jerhill
The essential thing for spreading REDHAWK components and devices across multiple machines is making sure that your CORBA communication works correctly between the machines. This usually amounts to configuring /etc/omniORB.cfg correctly. First, on one machine, you should have omniNames and omniEvents running, and setup your config per section 2.6 of the documentation. For reference:
InitRef = NameService=corbaname::127.0.0.1
InitRef = EventService=corbaloc::127.0.0.1:11169/omniEvents
On the second machine, your InitRef's must point to the first machine. If the first machine was 192.168.1.100, then your second machine's config could contain:
InitRef = NameService=corbaname::192.168.1.100
InitRef = EventService=corbaloc::192.168.1.100:11169/omniEvents
You should be able to verify this is working correctly on the second machine with:
$ nameclt list
The next issue you need to tackle is making sure that CORBA objects are listening on the appropriate network interfaces, and are publishing information in their IORs that allows them to be reached. In each of your config files, I recommend you add a line to tell omniORB what endpoint CORBA objects created on that machine should listen on. For example, on your first machine:
endPoint = giop:tcp:192.168.1.100:
endPoint = giop:unix:
This tells omniORB that CORBA objects should listen on a TCP port of their choosing on 192.168.1.100. It also adds a Unix pipe for fast access by objects on the same machine. omniORB will publish this information in the IOR for that object. What you choose here is important - if you use an IP that other machines can't reach, or use a hostname that other machines can't resolve then CORBA connections will fail.
After you've configured the endPoint setting on both machines, you may find it useful to inspect the information contained in your IORs. If you can access the naming service then you can retrieve IORs for your objects. For example, if you had a domain named 'REDHAWK_DEV' running, you can get the domain manager's IOR via:
$ nameclt resolve REDHAWK_DEV/REDHAWK_DEV
Then, feed the IOR to catior:
$ catior IOR:012345...
catior will decypher the IOR for you and show you what address and port a client would connect to.
Based on the fact that programs on B can see the name service on A, then I assume that the problem relates to Device/Device Manager configuration.
Make sure that the Device Manager on B meets these criteria:
the id attribute of the deviceconfiguration element of the dcd.xml file is unique
the id attribute of the GPP's componentinstantiation element on the dcd.xml file is unique
the name attribute of the namingservice element on the dcd.xml file is the Domain you are trying to connect to (of the form DomainName/DomainName)
you do not have a Domain Manager running on B that has a colliding name with the Domain Manager on A (an error should occur if you do that)
If these criteria are met and your system still does not work, please post the stdout from running nodeBooter from command-line for both the Device Manager that's not registering and the Domain Manager you're trying to register with.

Azure InputEndpoints block my tcp ports

My Azure app hosts multiple ZeroMQ Sockets which bind to several tcp ports.
It worked fine when I developed it locally, but they weren't accessible once uploaded to Azure.
Unfortunately, after adding the ports to the Azure ServiceDefinition (to allow access once uploaded to azure) every time I am starting the app locally, it complains about the ports being already in use. I guess it has to do with the (debug/local) load balancer mirroring the azure behavior.
Did I do something wrong or is this expected behavior? If the latter is true, how does one handle this kind of situation? I guess I could use different ports for the sockets and specify them as private ports in the endpoints but that feels more like a workaround.
Thanks & Regards
The endpoints you add (in your case tcp) are exposed externally with the port number you specify. You can forcibly map these endpoints to specific ports, or you can let them be assigned dynamically, which requires you to then ask the RoleEnvironment for the assigned internal-use port.
If, for example, you created an Input endpoint called "ZeroMQ," you'd discover the port to use with something like this, whether the ports were forcibly mapped or you simply let them get dynamically mapped:
var zeromqPort = RoleEnvironment.CurrentRoleInstance.InstanceEndpoints["ZeroMQ"].IPEndpoint.Port;
Try to use the ports the environment reports you should use. I think they are different from the outside ports when using the emulator. The ports can be retrieved from the ServiceEnvironment.
Are you running more than one instance of the role? In the compute emulator, the internal endpoints for different role instances will end up being the same port on different IP addresses. If you try to just open the port without listening on a specific IP address, you'll probably end up with a conflict between multiple instances. (E.g., they're all trying to just open port 5555, instead of one opening 127.0.0.2:5555 and one openining 127.0.0.3:5555.)

Resources