Experimental Environment
1. Mac OSX 10.9
2. Vagrant 1.7.2
3. VirtualBox-4.3.14-95030-OSX
4. CentOS6.5.box
5. Nginx 1.6.2
6. NodeJS 0.12.2
Items from 2 to 4 can be downloaded from here, while the installation of Item[5] is at its official document, Item[6] at this site.
Install Vagrant And Deploy Nginx, NodeJS On Vagrant
Firstly, invoke the following prompt for preparation:mkdir ~/vagrant mkdir ~/vagrant/box mkdir ~/vagrant/dev mv ~/Download/centos6.5.box ~/vagrant/box
The `box` subdir is for our .box file, while `dev` subdir is for current "Vagrantfile" instance.
Now let's initial our first vagrant environment with commands as below:
vagrant box add centos ~/vagrant/box/centos6.5.box # Load the centos6.5.box into VirtualBox cd ~/vagrant/dev vagrant init centos # Initial the above box, which will generate the 'Vagrantfile' file vagrant up # Start up the vagrant environment corresponding to config in the 'Vagrantfile' file vagrant ssh # ssh to the vagrant environment
In which, 'Vagrantfile' is the place where configurations resides, we'll see it later. `vagrant ssh` command is the abbreviation of `vagrant ssh default`, since we don't specify a name explicitly for current vagrant environment in 'Vagrantfile', it applies 'default' as its name.
Some relative and commonly-used vagrant commands are listed here for reference (we could simply invoke `vagrant` to check out elaborate information on sub-commands):
vagrant halt # Close current vagrant env and save data and cache on disk vagrant destroy # Close current vagrant env and dispose all the data. The next time when calling `vagrant up`, it will initial vagrant upon 'Vagrantfile' from scratch vagrant global-status # list current vagrant envs status
After logging in the vagrant environment, we could install Nginx and NodeJS as illustrated in the aforementioned URL. As for Nginx, root user is needed. For vagrant env, the default root's password is 'vagrant'.
Implement HelloWorld Upon NodeJS And Access From Host's Browser
In the 'default' vagrant env, `vim ~/helloworld.js`:var http = require('http'); http.createServer(function (req, res) { console.log(req.url); res.writeHead(200, {'Content-Type': 'text/plain', 'Content-Type': 'application/json;charset=utf-8'}); res.end('Hello Jason!'); }).listen(1337, "0.0.0.0"); console.log('Server running at http://0.0.0.0:1337/');
In which, we should listen to '0.0.0.0' rather than '127.0.0.1' provided that we intend to access it from our host's browser later on. The reason is well-explained here (Empty reply from server - can't connect to vagrant vm w/port forwarding).
After editing this .js file, we could fire it up via `node helloworld.js`. Next, open a new prompt window, login to the same vagrant env and execute `curl 127.0.0.1:1337`, we should see the html content returning from NodeJS server.
However, we cannot access this webpage through host's browser since the vagrant env and host resides in totally different IP segments. This could be solved by port forwarding technique, which is well-illustrated in the official document.
In our scenario, we simply add the following configuration in 'Vagrantfile' file.
config.vm.network :forwarded_port, host: 4567, guest: 1337
In this way, we could access at http://127.0.0.1:4567 from host machine to the NodeJS server in vagrant env.
Mask NodeJS With Nginx
Now, we are going to mask NodeJS with Nginx, though there's only one NodeJS server at this time.Configuration of Nginx is as follows, via `vim /etc/nginx/conf.d/virtual.conf`:
upstream nodejs { server 127.0.0.1:1337; keepalive 64; } server { listen 80; server_name 127.0.0.1; access_log /var/log/nginx/test.log; location / { proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; proxy_set_header X-Nginx-Proxy true; proxy_set_header Connection ""; proxy_pass http://nodejs; } }
By masking with Nginx, we should access http://127.0.0.1:80, then Nginx will assign our http request to its upstream (In current scenario, it is 127.0.0.1:1337). Start nginx via command `service nginx start` in root user.
Meanwhile, we should change our 'Vagrantfile' file so as to 'port forwarding' to 127.0.0.1:80.
config.vm.network :forwarded_port, host: 4567, guest: 80
Restart vagrant env by `vagrant reload`, login to vagrant env starting Nginx as well as NodeJS server. Eventually, we should be able to access NodeJS server at http://127.0.0.1:4567 from host.
Create Box From Current Vagrant Environment
To obtain a snapshot of current vagrant env, in which Nginx and NodeJS have installed, we could create a .box file from current vagrant env via command:vagrant package --output /yourfolder/OUTPUT_BOX_NAME.box
Create Multiple Vagrant Environments In A Single Vagrantfile
After all the work above, we are ready to create multiple vagrant envs in a single 'Vagrantfile' file, which looks as follows:Vagrant.configure(2) do |config| #config.vm.box = "jason_web" #config.vm.network :forwarded_port, host: 4567, guest: 80 config.vm.define :node1 do |node1| node1.vm.box = "jason_web" node1.vm.host_name = "node1" node1.vm.network :forwarded_port, host: 4567, guest: 80 node1.vm.network "private_network", ip:"192.168.10.10" config.vm.provider :virtualbox do |vb| vb.customize ["modifyvm", :id, "--memory", "1024"] vb.customize ["modifyvm", :id, "--cpus", "2"] end end config.vm.define :node2 do |node2| node2.vm.box = "jason_web" node2.vm.host_name = "node2" node2.vm.network "private_network", ip:"192.168.10.11" config.vm.provider :virtualbox do |vb| vb.customize ["modifyvm", :id, "--memory", "512"] vb.customize ["modifyvm", :id, "--cpus", "2"] end end config.vm.define :node3 do |node3| node3.vm.box = "jason_web" node3.vm.host_name = "node3" node3.vm.network "private_network", ip:"192.168.10.12" config.vm.provider :virtualbox do |vb| vb.customize ["modifyvm", :id, "--memory", "512"] vb.customize ["modifyvm", :id, "--cpus", "2"] end end config.vm.define :node4 do |node4| node4.vm.box = "jason_web" node4.vm.host_name = "node4" node4.vm.network "private_network", ip:"192.168.10.13" config.vm.provider :virtualbox do |vb| vb.customize ["modifyvm", :id, "--memory", "512"] vb.customize ["modifyvm", :id, "--cpus", "2"] end endThe configuration items are all self-explained well in the above configuration. The obvious difference between 'node1' and the others is that it has a port forwarding setting for the purpose of accessing Nginx service running at 'node1'.
If we intend to ssh from nodeA to nodeB, the default password for ssh is 'vagrant', which is the same as the root's password.
Login 'node1' and reconfigure the Nginx 'virtual.conf' as follows, then start it up!
upstream nodejs { server 192.168.10.10:1337; server 192.168.10.11:1337; server 192.168.10.12:1337; server 192.168.10.13:1337; keepalive 64; } server { listen 80; server_name 127.0.0.1; access_log /var/log/nginx/test.log; location / { proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; proxy_set_header X-Nginx-Proxy true; proxy_set_header Connection ""; proxy_pass http://nodejs; } }
Eventually, login to each node and start NodeJS server respectively. At this time, we should be able to access Nginx service from http://127.0.0.1:4567 on host machine, and http requests is distributed to different NodeJS servers.
Performance Benchmark Current Webserver
We could use Apache Benchmark toolkit to test our distributed webserver, whose command resembles:ab -k -c 350 -n 20000 http://127.0.0.1:4567/
'-c' means 'concurrent', -k for 'keepalive', while '-n' stands for 'total request amount'. For more detailed guide on how to take advantage of it to the maximum, we could refer to this post.
For Mac OSX, there's a bug on `ab` command, which could be patched illustrating in this link.
Reference
1. Nginx Tutorial - Proxy to Express Application, Load Balancer, Static Cache Files
2. mac下vagrant 的使用入门
3. VAGRANTDOCS - GETTING STARTED
4. Removing list of vms in vagrant cache
5. How to run node.js Web Server on nginx in Centos 6.4
6. NodeJs的安装 Hello World!
No comments:
Post a Comment