📜 ⬆️ ⬇️

Ruby on Rails on Windows with performance tests

“The pledge of friendship is the difference of individuals” Julian Semenov.
More and more, Windows developers are interested in Ruby, a dynamic high-level programming language. The framework for creating Ruby on Rails web applications has played a significant role here. Development on the "rails" is simple and exciting. Due to the high dynamics of Ruby, the developer opens a lot of tools, with a relatively small amount of code, you get rich functionality.

This article is well-suited for novice web programmers and those who are thinking of starting to work with Ruby on Rails. It will address such questions:Finally, you will find tests comparing the performance of various variants of running Ruby applications on Windows and Ubuntu.

Setting the working environment


')
First you need to download and install the Web Platform Installer, run it, click on “Options” and in the “Display additional scenarios” field add a link to the Helicon Zoo Feed: http://www.helicontech.com/zoo/feed/



After that, the Zoo tab will appear in the Web Platform Installer, which contains the “Applications”, “Packages”, “Modules”, and “Engines” sections:



Installing Ruby on Rails



In the "Engines" section, you can install various frameworks, including Ruby on Rails 3.1 and 2.3. In addition, Ruby 1.8 and 1.9 are also available here. By default, installing Rails 3 puts Ruby 1.9 as a dependency. For Rails 2, Ruby 1.8 will be shipped.

For convenience, the Packages section offers the Ruby Hosting Package, which includes the following components:

Creation of the first website



To create a new web application, it is convenient to use WebMatrix and IIS Express. On the “Zoo” tab, in the “Packages” section, there is the “WebMatrix Templates” package, which provides various templates-blanks, including for Ruby on Rails.

If you do not already have WebMatrix, it will be automatically installed along with the WebMatrix Templates package. Be prepared that downloading and installing all the packages may take some time. After installing the templates, start WebMatrix and on the start page select "Site from template" and then "Rails Site":



After creating the Rails Site, if you go to the specified URL or click "Run", you will see a page with instructions:



The template is designed to create Rails application branches 2.3, 3.0 or 3.1. At the moment, there is no application in the site directory yet, only the prepared configuration files. Let's create it by calling the following command:

rails new .

If the team does not specify a specific version of Rails, the latest available will be used. In our case, we used the “Ruby Hosting Package” package, which contains three different versions of Rails at once, and the most recent of them is 3.1. Therefore, the team will create a stub based on Rails 3.1.

Now if you refresh the page, you will see the standard Ruby on Rails greeting:



Development environment



To edit the code you need an editor or development environment. If you prefer the functionality of a full-fledged IDE, with a debugger and means for refactoring, you can consider the following programs:Each IDE offers a wealth of opportunities for developing and testing Ruby applications, and also supports version control systems.

For those who are used to using simpler solutions are available:To write the example, we used Aptana:



MVC



Ruby on Rails is based on the model-view-controller architecture (model, view, controller - MVC). This approach has the following advantages:The model describes the structure of the database in terms of object-oriented programming. So in Rails, a model is an ordinary class that inherits all the necessary functionality from the class ActiveRecord :: Base. An instance (object) of such a class describes one row from the corresponding database table. Thus, the models hide from the developer the subtleties of working with a specific DBMS.

A view is the interface itself that the user sees. At this level, the developer makes templates that convert to HTML, CSS, or JavaScript code.

The controller links the model and the view. Usually it is in the controller that the main logic is placed. In essence, controllers are Ruby classes. Each public controller method is called an action. If your controller is called Home and has a public index method in it, then usually by calling the browser / home / index you will call the action index.

When a request comes to an application, the routing mechanism (in the config / routes.rb file) determines which controller is responsible for this type of request. In addition to the URL address itself, many conditions can be taken into account, for example, you can use different controllers for different browsers, for mobile clients, etc.

So, choosing the controller determines the action that will process the request. Here you can also apply a lot of conditions. Directly in action, some kind of computation or work with the database takes place. When the action has fulfilled, it is time presentation. In the templates, you can transfer the data obtained from the database or some result. Normal HTML will be generated from the templates (there are also templates for JavaScript and CSS) and the page with the answer will be sent to the user.

We write application



A classic example for Rails is usually the creation of the simplest blog. We will not deviate from the traditions. So, let's delete the file with the greeting - public / index.html and create the Home controller with the Index action - this will be the main blog page. To do this, run the following command, while in the application directory:

rails g controller home index

Now if we query / home / index, we will get a page from the template created for the index action:



Next, we will create a simple Post model that will describe each individual blog post in the database. In Ruby code, the model looks like a class, and in a database, it looks like a table. Thus, an object of class Post is a row in the corresponding table.

To create a model, you can call the command “rails g model Post ...”, however let's use a more convenient means - scaffolding (scaffolding - construction wood). The rails g scaffold command creates, in addition to the model class itself and tests for it, action stubs and presentation templates for creating, editing and deleting model objects. Run the following command:

rails g scaffold Post name:string title:string content:text

We’ll get the Post model in app \ models \ post.rb, the Posts controller in app \ controllers \ posts_controller.rb, with index, show, new, edit, update, create, and destroy actions, as well as the database migration script in the db \ migrate directory . The team also created test stubs and HTML templates. It is important to note that we have not written any code yet.

Let's call a command that will create a database (if it does not already exist), as well as a table of posts with the fields name, title and context, as described above:

rake db:migrate

The database migration command is used to create or modify the database structure in accordance with our object model. It needs to be called every time you change something in the application model. All the magic of fitting the database structure to our model occurs automatically, and the data already recorded in the database will be saved.

Note that in the specific example Sqlite is used, in Rails this is the default database. However, the rails support a lot of other DBMS, while hiding the specifics of working with them.

Posts controller actions are now available at / posts /.



Clicking on the link "New Post" we will see the form:



Filling in all the fields, we get to the page of the new post:



Once again, no code has yet been written by hand. Now let's make some changes. For example, it may be necessary to specify the name and title of the post so that this field is always filled in the database. Fortunately, Rails provides a very simple validation mechanism. It is enough to correct the model file as follows:

 class Post < ActiveRecord::Base validates :name, :presence => true validates :title, :presence => true, :length => { :minimum => 5 } end 


Here we indicate that filling in the “name” and “title” fields is mandatory, and the “title” field must contain at least 5 characters. Migration is not necessary because The validators are not directly connected to the base, the check is performed at the level of a Ruby code.

If now, for example, do not enter the "name" field, we get an error:



Let's complicate the task and add comments. Create a Comment model with the following command:

rails g model Comment commenter:string body:text post:references

Note the "post: references" parameter. He links the comments table to the posts table.

Update the database:

rake db:migrate

Now let's set the “has many” relationship for the Post model:

 class Post < ActiveRecord::Base validates :name, :presence => true validates :title, :presence => true, :length => { :minimum => 5 } has_many :comments, :dependent => :destroy end 


The code is intuitive. It turns out that every Post object can have a lot of comments. : dependent =>: destroy indicates that when deleting a post, its comments should also be deleted. Since this time we did not use the scaffolding mechanism to create a comment model, we need to generate the corresponding controller:

rails g controller Comments

In the config \ routes.rb file, replace the line “resources: posts do” with:

 resources :posts do resources :comments end 


Thus, we indicate how the controller will be available with comments. In this case, it is embedded in “posts”, i.e. the links will be: http: // localhost: 41639 / posts / 1 / comments / 3

Next, you need to update the app \ views \ posts \ show.html.erb template so that you can post comments. After:

 <p> <b>Content:</b> <%= @post.content %> </p> 


add:

 <h2>Comments</h2> <% @post.comments.each do |comment| %> <p> <b>Commenter:</b> <%= comment.commenter %> </p> <p> <b>Comment:</b> <%= comment.body %> </p> <p> <%= link_to 'Destroy Comment', [comment.post, comment], :confirm => 'Are you sure?', :method => :delete %> </p> <% end %> <h2>Add a comment:</h2> <%= form_for([@post, @post.comments.build]) do |f| %> <div class="field"> <%= f.label :commenter %><br /> <%= f.text_field :commenter %> </div> <div class="field"> <%= f.label :body %><br /> <%= f.text_area :body %> </div> <div class="actions"> <%= f.submit %> </div> <% end %> 




Finally we describe the logic of the controller in app \ controllers \ comments_controller.rb

 class CommentsController < ApplicationController def create @post = Post.find(params[:post_id]) @comment = @post.comments.create(params[:comment]) redirect_to post_path(@post) end def destroy @post = Post.find(params[:post_id]) @comment = @post.comments.find(params[:id]) @comment.destroy redirect_to post_path(@post) end end 


Now everything is ready and you can add comments to the post:



So, the main functionality is implemented. As a final step, let's protect some actions so that an outsider does not have access to them. A more correct approach is to use registration, sessions, cookies, etc., but for simplicity we will take the usual Basic authentication, especially in Rails it is added in one line. In posts_controller.rb, write:

http_basic_authenticate_with :name => "admin", :password => "123", :except => [:index, :show]

Here the login and password are strictly specified. The: except option excludes the actions: index and: show - no authentication is required for them.



Deploy to server



So, we have written the application and now we want to post it online. To do this, configure the Windows server to work with Rails. We need to repeat the first few steps from the beginning of the article, which we did to deploy the working environment. You need to install the Microsoft Web Platform Installer, add the Helicon Zoo feed to it and install the Ruby Hosting Package from the Zoo repository. Before installing, you should make sure that in the Web Platfrom Installer settings it is specified to install applications under IIS, and not under IIS Express. Now the server is ready to accept our application. Currently, Windows 2008 and 2008 R2, 32 and 64 bit versions are supported from server platforms.

Now we will create an empty web site on the server using standard tools such as IIS Manager or hosting panel. Next you need to upload our application to the site via FTP or WebDeploy. In the case of WebDeploy, the necessary rights to the folders will also be distributed. You can also use Git or another version control system, but this is outside the scope of this article.

Helicon Zoo Module was originally developed with the calculation of configuring hosting solutions. So all applications under it are divided and do not overlap. The module itself with the default settings works in automatic mode, creating one worker (process handler) when the load is low or adding workers up to the number of cores to give maximum performance if the load on the application increases.

In Helicon Zoo the concept of engines (engines) and applications (applications) is used. So in the engines it is determined what to run and how, by what protocol and on which port, how many minimum and maximum workers are allowed and similar global settings that are set globally in the applicationHost.config file. Then, already under the site, you can create an application that uses a specific engine and pass it the necessary parameters for the operation of this application. This allows you to separate the work of the hosting administrator from clients, and clients from each other. For more information about the settings of the Helicon Zoo Module, please read here: http://www.helicontech.com/zoo/module.htm (English)

Pay attention to the deploy.rb file in the root directory of the site, as well as the DEPLOY_FILE and DEPLOY_LOG settings in the web.config. The zoo module performs deploy.rb every time the IIS pool is started. This approach can be useful to those who do not have administrative privileges on the server. After all, for deployment, most likely, you will need to perform "bundle install" or apply database migration. To do this, simply restart your application on the server and the deploy.rb file will be executed automatically. The most popular commands are already registered in deploy.rb.

It is also worth remembering that the deploy.rb script is executed by the same Windows user that starts the IIS pool. As a rule, he has very limited rights and this should be considered when writing his commands. For example, the usual call of “bundle install” can lead to an error, since it is not possible to write directly to the Ruby installation directory. A good solution is to pre-save all the jams under the site, in a special directory vendor / cache, for which you need to call the “bundle package” command in the directory of your application before sending it to the server. And in deploy.rb, you should write the “bundle install - local - path vendor / gems” command.

Execute script execution errors can be read in the file specified in the DEPLOY_LOG variable.

The last thing I would like to draw attention to when scanning is the RACK_ENV variable in the web.config. In the web.config that comes from the WebMatrix template, the variable RACK_ENV is specified with the value “development”. This includes an appropriate Rails mode, more suitable for development. On the server, it is necessary to change the value to "production". By the way, it is “production” that is used by default.

Performance tests



Test machine as a server - Core 2 Quad 2.4 Ghz, 8 Gb RAM, gigabit network. To generate the load, a more powerful computer and Apache Benchmark were used with the command “ab.exe -n 100000 -c 100 –k”. Ubuntu 11.04 Server x64 was used to test Apache and Nginx. IIS 7 tests worked on Windows Server 2008 R2. Any virtualok - honest iron.

Three tests were performed. In the first Rails application should simply display the current time on the page in high resolution. Time is needed to ensure that the answers do not come from the cache. In the second test, read from the MySQL database, in the third record in the database.

Ruby 1.9.3, Rails 3.1.1 and MySQL 5.1.54 were used for the tests. In the case of HTTP transport, Thin was used as a backend. Neither Unicorn nor Passenger on Windows just work. In total, three configurations participated in the test: Windows + IIS 7.5 + Helicon Zoo + Thin, Ubuntu + Apache + Passanger, Ubuntu + Nginx + Thin.

Here are the results (the value on the graphs - requests per second):



Also according to the first test with the time output, we present more detailed graphs of ab:







findings



Ruby on Rails is an excellent framework that allows you to quickly and easily create various web applications. Of course the world of Ruby is not limited to them. In subsequent articles, we will look at Goliath and Sinatra.

I would like to note that Windows is a good platform for developing Ruby as well as launching applications in production. If earlier the difference in performance of Ruby on Linux and Windows systems was high, then now the performance, as well as the usability of using RoR on Windows, have greatly improved. So much so that now the question of performance when choosing a platform can be neglected against the background of other factors.


PS: The co-author of this article is Vyacheslav Shinkarenko. Because he is not invited to Habr, then his Twitter: https://twitter.com/#!/vyaces

Source: https://habr.com/ru/post/136086/


All Articles