The Heart Bit Hi, I’m Rafael Sales. I work as software engineer, specialized in Ruby, Java and JavaScript. I code tested, clean, fast, maintainable, and secure bits. https://rafaelsales.github.io/ Wed, 14 Nov 2018 15:57:03 +0000 Wed, 14 Nov 2018 15:57:03 +0000 Jekyll v3.7.4 AWS-SSH - Easy SSH to EC2 servers <p>Currently I work at <a href="http://buzzstarter.com">Buzzstarter Inc.</a>, and I’ve been working on the web app, which infrastructure is hosted in <a href="http://aws.amazon.com">Amazon Web Services</a>. In general, we don’t really need to SSH into EC2 instances because the deployment pipeline is fully automated with <a href="https://aws.amazon.com/opsworks">OpsWorks</a>, but in many cases it’s still useful to quickly jump into servers console. Here are some reasons you might want to do that:</p> <ul> <li>Check application health in detail when information provided by other services such as NewRelic, AirBrake, CloudWatch, Rollbar were not enough</li> <li>Perform <strong>Q</strong>uality <strong>A</strong>ssurance at system-level. E.g.: QA deployment changes that cause system packages to be updated</li> <li>Verify responsiveness of a particular server</li> </ul> <h3 id="the-problem">The problem</h3> <p>Our environments are very dynamic - we often make changes in our servers configuration and sometimes, due to unexpected issues, we have to shutdown or spin up a new EC2 instance, so our servers are constantly changing IP addresses. A while ago, I used to keep my SSH config (<code class="highlighter-rouge">~/.ssh/config</code>) with a mapping of server names with their IP addresses, but I was getting tired of updating that file due to constant changes.</p> <p>You probably heard about <a href="https://github.com/aws/aws-cli">AWS-CLI</a> - a tool that allows you to interact with Amazon infrastucture via command-line. Unfortunately, there’s really no easy way to make use of that to get access via SSH to your instances.</p> <p>For a while I was really dreaming of being able to SSH to any EC2 instance with just a friendly name in hand. It would be also pretty cool to list the instances per Stack (configured in OpsWorks), so that I could quickly jump into every server of one environment - let’s say I want to SSH into servers of Staging environment.</p> <h3 id="the-solution">The solution</h3> <p>Yesteday I launched <a href="https://github.com/buzzstarter/aws-ssh">AWS-SSH</a> - it’s a simple tool that made my dream come true. I think it’s a lot easier to show how useful is that by showing examples, so check out below how to setup and use it.</p> <h3 id="setting-up-the-tool">Setting up the tool</h3> <p><em>NOTE: the CLI can be run through both <code class="highlighter-rouge">aws-ssh</code> and <code class="highlighter-rouge">awssh</code>.</em></p> <ol> <li> <p>Make sure you have <code class="highlighter-rouge">aws-cli</code> installed and configured. Follow guide in https://github.com/aws/aws-cli</p> </li> <li> <p>Install aws-ssh gem: <code class="highlighter-rouge">gem install aws-ssh</code></p> </li> <li> <p>Create a file named <code class="highlighter-rouge">.awssh</code> with default options:</p> </li> </ol> <div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>``` profile: your-app-aws-cli-profile-name region: us-east-1 user: custom-machine-user-for-ssh ``` </code></pre></div></div> <h3 id="examples">Examples</h3> <ol> <li>List servers filtered by name <code class="highlighter-rouge">staging</code>. Here we use option <code class="highlighter-rouge">-so</code>, which is the short of <code class="highlighter-rouge">--show-only</code>, i.e., it will list only, and not try to SSH.</li> </ol> <div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>``` $ awssh -so staging ssh [email protected] =&gt; Buzzstarter Staging - staging-app ssh [email protected] =&gt; Buzzstarter Staging - staging-worker # All hosts in one-line (suitable for CSSH): [email protected] [email protected] ``` </code></pre></div></div> <ol> <li>SSH into first production app server. Here we use regex to filter server hostname.</li> </ol> <div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>``` $ awssh prod.*app1 user@prod-rails-app1:~$ # you can now interact with this server from now on ``` </code></pre></div></div> <ol> <li>In first example, you can observe the last line of the output contains a whitespace-separated list of servers. We can use that as an input to a Cluster-SSH tool in order to SSH into multiple servers at once. I’m gonna use <a href="https://github.com/dennishafemann/tmux-cssh">tmux-cssh</a> for example:</li> </ol> <div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>``` $ tmux-cssh $(awssh -so prod.*app | tail -1) ``` The result is: ![](/assets/images/tmux-cssh.png) </code></pre></div></div> <ol> <li>If you are user of OpsWorks, you can also filter by Stack name: The <code class="highlighter-rouge">-s</code> is the short of <code class="highlighter-rouge">--stack</code>, which value is a regex:</li> </ol> <div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>``` $ awssh -so -s qa ssh [email protected] =&gt; Buzzstarter QA - testing-app ssh [email protected] =&gt; Buzzstarter QA - testing-worker # All hosts in one-line (suitable for CSSH): [email protected] [email protected] ``` </code></pre></div></div> <hr /> <p>More information: https://github.com/buzzstarter/aws-ssh</p> <p>Contributions are welcome!</p> <p>Happy coding, folks!</p> Tue, 18 Aug 2015 07:50:00 +0000 https://rafaelsales.github.io/ruby/sqlite/threadsafe/concurrency/2015/08/18/aws-ssh/ https://rafaelsales.github.io/ruby/sqlite/threadsafe/concurrency/2015/08/18/aws-ssh/ ruby sqlite threadsafe concurrency SQLite thread-safety check <p>Before start using an <a href="http://en.wikipedia.org/wiki/Relational_database_management_system">RDMS</a> we should always evaluate which are its constraints and how we are planning to use it.</p> <p>We often implement multithread processes that access database. One simple example is acessing a database on a multithreaded application server, such as <a href="http://puma.io">Puma</a>, or on a multithreaded background processing framework, such as <a href="http://sidekiq.org">Sidekiq</a>.</p> <p>When running code that access a database on such multithreaded environments, we need to verify if the database is ready to accept connections from multiple threads and, sometimes, if a single connection can be shared with multiple threads.</p> <h3 id="a-real-scenario">A real scenario</h3> <p>Recently, I was working on an application that uses in-memory SQLite and the team decided to migrate from <a href="https://github.com/resque/resque">Resque</a> - <em>a process-based background processing framework</em> - to Sidekiq, which is thread-based. This change begs the question:</p> <h3 id="is-sqlite-thread-safe">Is SQLite thread-safe?</h3> <p>SQLite was built to work on three diferent modes in this regard and the mode is defined by a compilation flag named <code class="highlighter-rouge">THREADSAFE</code>. It can have three values:</p> <ul> <li><code class="highlighter-rouge">THREADSAFE=0</code>: It’s unsafe to use SQLite in a multithreaded application - it ommits all <a href="http://en.wikipedia.org/wiki/Mutual_exclusion">mutexing</a> code on the compiled code;</li> <li><code class="highlighter-rouge">THREADSAFE=1</code>: It’s safe to use SQLite in a multithreaded application and multiple threads can use the same connection. <strong>This is the default option when compiling SQLite</strong>;</li> <li><code class="highlighter-rouge">THREADSAFE=2</code>: It’s safe to use SQLite in a multithreaded application but each connection must be used by a single thread at a time.</li> </ul> <h3 id="checking-thread-safety-level-of-sqlite-installation">Checking thread-safety level of SQLite installation</h3> <h4 id="in-ruby"><strong>In Ruby</strong></h4> <p>Open interactive Ruby console: <code class="highlighter-rouge">$ irb</code> and execute:</p> <div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="no">SQLite3</span><span class="o">::</span><span class="no">Database</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="s2">":memory:"</span><span class="p">).</span> <span class="nf">execute</span><span class="p">(</span><span class="s2">"PRAGMA compile_options"</span><span class="p">).</span> <span class="nf">map</span><span class="p">(</span><span class="o">&amp;</span><span class="ss">:first</span><span class="p">).</span><span class="nf">find</span> <span class="p">{</span> <span class="o">|</span><span class="n">option</span><span class="o">|</span> <span class="n">option</span> <span class="o">=~</span> <span class="sr">/THREADSAFE/</span> <span class="p">}</span> <span class="c1"># This will produce an output like "THREADSAFE=2"</span> </code></pre></div></div> <h4 id="on-a-c-program"><strong>On a C program</strong></h4> <p>Create a file named <code class="highlighter-rouge">sqlite_threadsafe.c</code> with following content:</p> <div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#include &lt;sqlite3.h&gt; </span> <span class="kt">int</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span> <span class="k">return</span> <span class="n">sqlite3_threadsafe</span><span class="p">();</span> <span class="p">}</span> </code></pre></div></div> <p>Then compile with:</p> <div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ gcc sqlite3_threadsafe.c -lsqlite3 -o sqlite3_threadsafe </code></pre></div></div> <p>And finally see the thread-safety level executing:</p> <div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ ./sqlite_threadsafe 2 # this is the value used on THREADSAFE compilation flag </code></pre></div></div> <h4 id="on-sqlite-console"><strong>On SQLite console</strong></h4> <p>Execute <code class="highlighter-rouge">PRAGMA compile_options</code> on SQLite console to see all the compile options, including the <code class="highlighter-rouge">THREADSAFE</code> option. E.g.:</p> <div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ sqlite3 SQLite version 3.8.5 2014-08-15 22:37:57 Enter ".help" for usage hints. Connected to a transient in-memory database. Use ".open FILENAME" to reopen on a persistent database. sqlite&gt; PRAGMA compile_options; ENABLE_FTS3 ENABLE_FTS3_PARENTHESIS ENABLE_LOCKING_STYLE=1 ENABLE_RTREE OMIT_AUTORESET OMIT_BUILTIN_TEST OMIT_LOAD_EXTENSION SYSTEM_MALLOC THREADSAFE=2 </code></pre></div></div> <p><strong>References:</strong></p> <ul> <li>https://www.sqlite.org/compile.html#threadsafe</li> <li>http://www.sqlite.org/cvstrac/wiki?p=MultiThreading</li> </ul> Sat, 11 Apr 2015 02:50:00 +0000 https://rafaelsales.github.io/ruby/sqlite/threadsafe/concurrency/2015/04/11/sqlite-thread-safe-check/ https://rafaelsales.github.io/ruby/sqlite/threadsafe/concurrency/2015/04/11/sqlite-thread-safe-check/ ruby sqlite threadsafe concurrency Why not use Cron in production <p>Cron is the simplest way to schedule tasks in *nix systems. Since it’s a mature tool, most of developers and companies have been using it in production without analyzing if it’s suitable for distributed systems.</p> <h3 id="why-not-use-cron">Why not use Cron?</h3> <p>Most of the web applications today try to benefit from distributed systems properties and I dare to say the most important ones on web are scalability and reliability. So, does Cron provide the reliability expected on web applications? See why not:</p> <ul> <li> <p><strong>Cannot run distributed</strong></p> <p>Cron jobs are setup in one single computer so, if that computer crashes, the application will miss important scheduled tasks until that server is back up or another server with same crontab configuration is spinned up.</p> </li> <li> <p><strong>Does not feature backfill</strong></p> <p>When a server hosting Cron is recovered from a crash, it does not automatically execute the jobs missed while the server was down. If a scheduled task is missed while the server is down, a person will need to execute the missed tasks manually.</p> <p><a href="http://en.wikipedia.org/wiki/Anacron">Anacron</a> is a tool that works in conjunction with Cron and does not assume the system is running continuously. However, Anacron does not run distributed.</p> </li> <li> <p><strong>Does not retry failures automatically</strong></p> <p>Cron jobs are not automatically retried on failure. I’ve seen cron jobs that access a database or an external service. When these fail, a reliable solution would retry the same job after some delay - usually an <a href="http://en.wikipedia.org/wiki/Exponential_backoff">exponential backoff formula</a> is a good choice to define the delay intervals between retries.</p> </li> </ul> <h3 id="solutions">Solutions</h3> <ul> <li> <p>For Ruby, there is this <a href="https://github.com/tobiassvn/sidetiq">Side<strong>t</strong>iq gem</a> that runs on top of <a href="https://github.com/mperham/sidekiq">Side<strong>k</strong>iq</a>. Here is an ideal setup to avoid the issues mentioned above:</p> </li> <li> <p>Use Side<strong>k</strong>iq’s <a href="https://github.com/mperham/sidekiq/wiki/Advanced-Options#workers">automatically retries</a>.</p> </li> <li> <p>Use Side<strong>t</strong>iq’s <a href="https://github.com/tobiassvn/sidetiq/wiki/Backfills">backfill feature</a>.</p> </li> <li> <p>Have at least <strong>two</strong> servers running Side<strong>k</strong>iq workers.</p> </li> <li> <p>Notify the application maintainers when the retries are exhausted. Look how to use Side<strong>k</strong>iq’s <code class="highlighter-rouge">sidekiq_retries_exhausted</code> feature at <a href="https://github.com/mperham/sidekiq/wiki/Error-Handling#configuration">Sidekiq Error Handling configuration</a>.</p> </li> <li> <p>There are some SaaS solutions out there. I found this <a href="https://crondash.com">Crondash</a> tool which has retry support. It also reports errors which is useful to monitor the application health. If you search for <em>online cron job</em> on web, you should find other similar SaaS available.</p> </li> </ul> <p>There should be many other solutions to the same problem. Just remember to choose one that supports retry, backfill and running in multiple servers.</p> <p>Please comment what solutions you are using for cron jobs that fulfills distributed system properties.</p> <p>Happy coding!</p> Mon, 16 Mar 2015 13:05:00 +0000 https://rafaelsales.github.io/ruby/cron/2015/03/16/why-not-use-cron-in-production/ https://rafaelsales.github.io/ruby/cron/2015/03/16/why-not-use-cron-in-production/ ruby cron The beginning of an era <p>Hi folks! Creating a blog is among my New Year’s resolutions. I’ll be writing about software engineering, doing my best to give unique contributions to software development community.</p> <p>All the code I write will be shared on <a href="https://github.com/rafaelsales">My GitHub</a>. Please feel free to contribute with any critics, suggestions and pull requests :)</p> <p>Happy coding!</p> Sat, 14 Mar 2015 00:00:55 +0000 https://rafaelsales.github.io/2015/03/14/the-beginning-of-an-era/ https://rafaelsales.github.io/2015/03/14/the-beginning-of-an-era/