DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Because the DevOps movement has redefined engineering responsibilities, SREs now have to become stewards of observability strategy.

Apache Cassandra combines the benefits of major NoSQL databases to support data management needs not covered by traditional RDBMS vendors.

The software you build is only as secure as the code that powers it. Learn how malicious code creeps into your software supply chain.

Generative AI has transformed nearly every industry. How can you leverage GenAI to improve your productivity and efficiency?

Related

  • Setting up Device Cloud: A Beginner’s Guide
  • Selenium vs Cypress: Does Cypress Replace Selenium?
  • Create Customizable Database App Systems With One Command
  • Virtual Reality and Augmented Reality in the Browser

Trending

  • SaaS in an Enterprise - An Implementation Roadmap
  • Software Delivery at Scale: Centralized Jenkins Pipeline for Optimal Efficiency
  • Understanding the Shift: Why Companies Are Migrating From MongoDB to Aerospike Database?
  • Go 1.24+ Native FIPS Support for Easier Compliance
  1. DZone
  2. Software Design and Architecture
  3. Cloud Architecture
  4. Deploying an Nchan-Powered PubSub Server on ECS

Deploying an Nchan-Powered PubSub Server on ECS

You won't need to learn JavaScript to get real-time updates with this module.

By 
Don Omondi user avatar
Don Omondi
·
Jan. 07, 19 · Tutorial
Likes (1)
Comment
Save
Tweet
Share
6.2K Views

Join the DZone community and get the full member experience.

Join For Free

The modern app is real-time. It doesn't matter whether it's a web app, desktop or mobile app. The notion of "Please refresh to see changes" is ancient history. Today, the fact that an app can show new comments, or similar actions as they happen — without a page refresh — is considered by many a minimum standard feature.

This means that developers must find ways to efficiently enable real-time, bi-directional communication between app clients and backend servers. One of the most used concepts to accomplish this task is the Publish-Subscribe pattern.

The Publish–Subscribe pattern, popularly abbreviated as pub/sub, is a messaging pattern where senders of messages, called publishers, do not program the messages to be sent directly to specific receivers, called subscribers, but instead categorize published messages into classes without knowledge of which subscribers, if any, there may be. Similarly, subscribers express interest in one or more classes and only receive messages that are of interest, without knowledge of which publishers there are, if any.

There are already a plethora of libraries that can help developers set up a quick PubSub server, especially within the Node.js and npm ecosystems. The highly popular socket.io quickly comes to mind as well as others like primus. But they all contain one potential drawback: they are all JavaScript-based!

This means, whether your backend is written primarily in PHP, Python, Java or Go, adding real-time communication using one of the popular libraries forces you to use and perhaps learn JavaScript.

For many developers, learning a whole new language just to add one feature can be a potential deal-breaker. For this reason, and others that we'll dive into, let me introduce you to Nchan, a non-JavaScript based pub/sub server.

Nchan is a scalable, flexible pub/sub server for the modern web, built as a module for the NGINX web server. It can be configured as a standalone server, or as a shim between your application and hundreds, thousands, or millions of live subscribers. It can buffer messages in memory, on-disk, or via Redis. All connections are handled asynchronously and distributed among any number of worker processes. It can also scale to many NGINX servers with Redis.

Convinced? Without further ado let's dive into how to deploy Nchan on an Alibaba Cloud Elastic Compute Service (ECS) instance.

Prerequisite: Elastic Compute Service (ECS) Instance

First, we'll require an up and running ECS instance. If you haven't already, sign up on Alibaba Cloud. You can use this link to get $300 worth of free trial products.

As you set up your ECS instance, let's have a brief look into some key considerations to make, in order to have the best performance possible for our pub/sub server.

The first key component is the deployment region. For best performance, select a region closest to your clients. This is because each client would have to connect to our pub/sub server and keep that connection alive to receive real-time messages. So you would rather have many low latency connections to clients (subscribers) and one high one back to your application server (publisher) than many high latency connections to clients and one low latency one back to your server. Interestingly, Nchan has a built-in ability to deploy many NGINX servers and sync all pub/sub messages via Redis. But this is an advanced scenario that most won't need.

Another thing to consider is the ECS instance type. Nchan is an NGINX module, so it naturally inherits NGINX's resource requirements, which is surprisingly minuscule – 128MB of RAM is enough to run the tiniest NGINX server! So literally any ECS instance can run an Nchan pub/sub server, right from the smallest to the largest. Feel free to choose whatever suits you well.

Another critical component is storage. The default is an Ultra Cloud Disk drive, which is fast enough for any pub/sub server. If you chose to buffer pub/sub messages in memory, then the storage chosen hardly matters. However, if your application is serving tens of thousands of connected pub/sub clients and you lack enough RAM, then you should consider switching to disk-based buffering and use the more performant SSD Cloud Disk.

Lastly, the system configuration. Alibaba Cloud's security will restrict ingress and outgoing traffic to a few ports. Make sure the NGINX port is one of them. Typically NGINX uses port 80 for unsecured HTTP traffic or 433 for the SSL secured equivalent.

With all the above taken into consideration, our new ECS instance is ready to go. Time to connect to it and prepare it for an Nchan deployment. If you are on windows, you can use Putty.

Preparing the Server

When I'm the only tenant on a CentOS server, one of the first things I do is to disable SELinux – permanently. With it on, you may sometimes run into weird bugs here and there that are a pain to debug. I normally use this command

sudo sed -i 's/enforcing/disabled/g' /etc/selinux/config /etc/selinux/config


Next thing is to install and enable the epel repository. This enables us to download and install the latest software for our Centos version. It's good practice to always use the latest versions of software, for many reasons, chiefly security, performance, and feature enhancements. Let's type these commands to do so.

sudo yum -y install wget
sudo wget https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
sudo rpm -Uvh epel-release-latest-7.noarch.rpm


The last steps we'll take in setting up the server is to download and install the git, zip and unzip libraries and thereafter update all software on our server. We'll use these commands.

sudo yum -y install git zip unzip
sudo yum -y update


From here on in, our server is ready to have NGINX and Nchan deployed. If need be, you can opt to restart the server, to ensure that all settings are picked up, and that some of them persist on reboots – like the potentially annoying selinux. You can use this command.

sudo shutdown -r now

Compiling NGINX with the Nchan Module

To use Nchan with NGINX, you would need to build NGINX from source and configure it with the Nchan module. The Nchan website has an overview of how to do it from various Linux flavors, however, in this article, we'll dive into details of how to do it from a CentOS 7.x server on ECS.

First, ensure that you have all the necessary build tools installed. If not, you can quickly install them using this command. By the way, even if you have them installed, running these commands should produce no side-effects.

sudo yum -y install git gcc gcc-c++ make zlib-devel pcre-devel openssl-devel


Clone the latest Nchan source code from its GitHub repository. This places the module under a folder called nchan.

git clone https://github.com/slact/nchan.git


Fetch the latest version of NGINX from its download page, v1.15.3 at the time of writing. You may opt to override it and fetch previous versions if you so wish.

wget http://nginx.org/download/nginx-1.15.3.tar.gz


Uncompress the tar file and cd into it.

tar xzvf nginx-1.15.3.tar.gz
cd nginx-1.15.3


Now for the main focus of this article. Build NGINX from the sources specifying Nchan as an added module.

sudo ./configure --add-module=../nchan --user=root --group=root --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid
sudo make
sudo make install


Check to make sure NGINX is properly installed by asking for its version. Run this command.

sudo /usr/local/nginx/sbin/nginx –v


This command should output something like this.

    nginx version: nginx/1.15.3

Configuring NGINX

Now that we can confirm that the custom build worked. Let's proceed to configure NGINX and Nchan.

First, create a symlink from our custom NGINX folder to the folder where NGINX would have been installed to should we have done so using the more common yum commands or rpm. Why? Almost any tutorial you find online will reference these places so it helps in getting assistance or debugging any issue. To do so, run these commands.

sudo ln -s /usr/local/nginx/conf/ /etc/nginx
sudo ln -s /usr/local/nginx/sbin/nginx /usr/sbin/nginx


Next, let's create a system init script that can register our custom built NGINX as a CentOS service. To do so, create a file in folder /etc/init.d let's name is NGINX.

sudo vi /etc/init.d/nginx


In it, paste the following content.

#!/bin/sh
#
# nginx - this script starts and stops the nginx daemon
#
# chkconfig:   - 85 15
# description:  NGINX is an HTTP(S) server, HTTP(S) reverse \
#               proxy and IMAP/POP3 proxy server
# processname: nginx
# config:      /etc/nginx/nginx.conf
# config:      /etc/sysconfig/nginx
# pidfile:     /var/run/nginx.pid

# Source function library.
. /etc/rc.d/init.d/functions

# Source networking configuration.
. /etc/sysconfig/network

# Check that networking is up.
[ "$NETWORKING" = "no" ] && exit 0

nginx="/usr/sbin/nginx"
prog=$(basename $nginx)

NGINX_CONF_FILE="/etc/nginx/nginx.conf"

[ -f /etc/sysconfig/nginx ] && . /etc/sysconfig/nginx

lockfile=/var/lock/subsys/nginx

make_dirs() {
   # make required directories
   user=`$nginx -V 2>&1 | grep "configure arguments:.*--user=" | sed 's/[^*]*--user=\([^ ]*\).*/\1/g' -`
   if [ -n "$user" ]; then
      if [ -z "`grep $user /etc/passwd`" ]; then
         useradd -M -s /bin/nologin $user
      fi
      options=`$nginx -V 2>&1 | grep 'configure arguments:'`
      for opt in $options; do
          if [ `echo $opt | grep '.*-temp-path'` ]; then
              value=`echo $opt | cut -d "=" -f 2`
              if [ ! -d "$value" ]; then
                  # echo "creating" $value
                  mkdir -p $value && chown -R $user $value
              fi
          fi
       done
    fi
}

start() {
    [ -x $nginx ] || exit 5
    [ -f $NGINX_CONF_FILE ] || exit 6
    make_dirs
    echo -n $"Starting $prog: "
    daemon $nginx -c $NGINX_CONF_FILE
    retval=$?
    echo
    [ $retval -eq 0 ] && touch $lockfile
    return $retval
}

stop() {
    echo -n $"Stopping $prog: "
    killproc $prog -QUIT
    retval=$?
    echo
    [ $retval -eq 0 ] && rm -f $lockfile
    return $retval
}

restart() {
    configtest || return $?
    stop
    sleep 1
    start
}

reload() {
    configtest || return $?
    echo -n $"Reloading $prog: "
    killproc $nginx -HUP
    RETVAL=$?
    echo
}

force_reload() {
    restart
}

configtest() {
  $nginx -t -c $NGINX_CONF_FILE
}

rh_status() {
    status $prog
}

rh_status_q() {
    rh_status >/dev/null 2>&1
}

case "$1" in
    start)
        rh_status_q && exit 0
        $1
        ;;
    stop)
        rh_status_q || exit 0
        $1
        ;;
    restart|configtest)
        $1
        ;;
    reload)
        rh_status_q || exit 7
        $1
        ;;
    force-reload)
        force_reload
        ;;
    status)
        rh_status
        ;;
    condrestart|try-restart)
        rh_status_q || exit 0
            ;;
    *)
        echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload|configtest}"
        exit 2
esac


Make sure the init script has the correct permissions to run. Run this command to do so.

sudo chmod +x /etc/init.d/nginx


Now we can reload the system daemon and tell our NGINX powered Nchan pub/sub server to start on system boot. Use these commands.

sudo systemctl daemon-reload
sudo systemctl start nginx
sudo service nginx status
sudo chkconfig nginx on


Now, NGINX is fully configured with a custom module and built. Now, it's time to configure its pub/sub paramters.

sudo service nginx restart


With the above configuration, you can now publish messages to channels by sending a post request with data to /pub?id=channel_id , and subscribe by pointing Websocket, EventSource, or NchanSubscriber.js to sub/?id=channel_id.

For browser implementations, I'd greatly advocate using NchanSubscriber.js, a companion Nchan JavaScript library. I've contributed code to it, so trust me when I say, it's that simple!

Enjoy building modern real-time apps with Nchan, NGINX and Alibaba Cloud ECS!

Entity component system Cloud computing Command (computing) mobile app Alibaba Cloud

Opinions expressed by DZone contributors are their own.

Related

  • Setting up Device Cloud: A Beginner’s Guide
  • Selenium vs Cypress: Does Cypress Replace Selenium?
  • Create Customizable Database App Systems With One Command
  • Virtual Reality and Augmented Reality in the Browser

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!