<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[IT guy speaking]]></title><description><![CDATA[IT guy speaking]]></description><link>https://igkuz.ru/</link><image><url>https://igkuz.ru/favicon.png</url><title>IT guy speaking</title><link>https://igkuz.ru/</link></image><generator>Ghost 5.50</generator><lastBuildDate>Wed, 20 May 2026 04:02:28 GMT</lastBuildDate><atom:link href="https://igkuz.ru/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[Building a dev setup for the AI era]]></title><description><![CDATA[Building an AI-ready dev setup with Docker Compose, devcontainers, Claude Code, scoped secrets, VPN access, and safer defaults.]]></description><link>https://igkuz.ru/building-a-dev-setup-for-the-ai-era/</link><guid isPermaLink="false">69ff008f4e9347710787e5b8</guid><category><![CDATA[AI]]></category><category><![CDATA[Containers]]></category><category><![CDATA[devops]]></category><category><![CDATA[DX]]></category><dc:creator><![CDATA[Igor Kuznetsov]]></dc:creator><pubDate>Sat, 09 May 2026 09:47:49 GMT</pubDate><media:content url="https://igkuz.ru/content/images/2026/05/featured-image-ai-dev-setup-1600.jpg" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="https://igkuz.ru/content/images/2026/05/featured-image-ai-dev-setup-1600.jpg" alt="Building a dev setup for the AI era"><p>We already had a local development setup.</p>
<p>It was not beautiful, but it worked. There was a <code>docker-compose.yml</code> file. I could start the services I needed and do my job. Some engineers used Docker Compose too. Others ran parts of the system directly on their machines. People used different editors as well: VS Code, Cursor, Zed, or just a terminal. For a backend project, this was normal.</p>
<p>Then Claude Code entered the picture.</p>
<p>That changed how I looked at the whole setup. The question was no longer just:</p>
<blockquote>
<p>Can a developer run the project locally?</p>
</blockquote>
<p>It became:</p>
<blockquote>
<p>Can a developer and an AI agent work in this project without giving the agent my whole laptop?</p>
</blockquote>
<p>That second question is harder.</p>
<p>When I use an AI coding agent, I want it to do actual work. I want it to read files, run tests, inspect errors, make changes, and try again. If I have to approve every small command, the flow breaks. At some point the tool starts feeling like a very slow autocomplete.</p>
<p>But the other extreme is also uncomfortable. Running an agent in a permissive mode directly on the host gives it access to much more than the project. My laptop has SSH keys, shell history, browser data, personal config, other repositories, and a lot of accidental state. Even if I trust the tool, that is too much surface area.</p>
<p>So this work was not about using devcontainers because they are fashionable. I was trying to build a better local development setup for a world where AI agents are part of the workflow.</p>
<p>The setup needed to stay familiar for people who already used Docker Compose. I wanted it to feel native for people working in IDEs. Another requirement: give Claude Code enough room to be useful without exposing the whole host.</p>
<p>In this article, I will walk through how I took an existing Docker Compose setup and added service-specific devcontainers, ran Claude Code inside them, kept secrets and VPN access scoped to the project, and looked at what still needs stronger guardrails.</p>
<h2 id="the-setup-was-fine-until-it-was-not">The setup was fine until it was not</h2>
<p>Before this work, the local workflow was straightforward.</p>
<p>Clone the repo. Start Docker Compose, or run the services locally. Turn on the corporate VPN when staging services were needed. Run Claude Code on the host, or run it somewhere else if you had your own setup.</p>
<p>Nothing was obviously broken. That is probably why this kind of work is easy to postpone. The pain is spread out across small things.</p>
<p>One person runs everything through Docker Compose. Another person runs one service locally and the rest in containers. Debugging works in one editor but not in another. None of these problems is dramatic, but they add up.</p>
<p>VPN access had the same shape. Some workflows needed staging services behind the corporate VPN. Turning the VPN on globally worked, but it affected the whole machine. Routing changed. DNS changed. Other unrelated work could be affected. The project needed VPN access sometimes; my whole laptop did not.</p>
<p>Claude Code made these tradeoffs more visible.</p>
<p>An AI agent is useful when it can move with fewer interruptions. But fewer interruptions usually mean broader permissions. If those permissions are on the host, I do not like the risk. If they are inside a project container, I can live with the tradeoff.</p>
<p>A container is not a perfect security boundary. I would not describe this as &quot;secure&quot; in an absolute sense. But it is still a smaller box than my laptop, and that matters.</p>
<p>The rough principle became:</p>
<blockquote>
<p>Give the agent room to work, but make the room smaller.</p>
</blockquote>
<h2 id="what-changed-with-ai-agents">What changed with AI agents</h2>
<p>I was thinking a lot about <a href="https://www.youtube.com/watch?v=kgwvAyF7qsA&amp;ref=igkuz.ru">Dan Guido&apos;s talk</a> on how Trail of Bits rebuilt their company around AI. The detail that stayed with me was not a specific repository or tool. It was the idea that adopting AI is not just installing a CLI.</p>
<p>If you want people to use these tools seriously, you need a workflow around them. You need defaults. You need a good first run. You need some policy. You need a place where the tool can act without forcing the developer to make a security decision every two minutes.</p>
<p>AI adoption needs the same standards as any other tool. If every developer has to decide how to install the agent, where to run it, what permissions are OK, and where config belongs, they spend energy before doing real work. A standard dev environment removes one of those decisions: the project opens the same way, the agent runs in the same kind of container, shared settings live in the repo, and personal auth stays personal.</p>
<p>That matched my experience.</p>
<p>If Claude Code asks for approval all the time, people will use it less. Or they will give it broad permissions in the easiest place: directly on the host. Nobody wants to fight their tools all day.</p>
<p>I wanted a middle ground:</p>
<ul>
<li>Claude Code runs inside the devcontainer</li>
<li>the main filesystem it sees is the project</li>
<li>secrets are mounted only when needed</li>
<li>project guidance lives in the repo</li>
<li>personal auth stays outside the repo</li>
<li>later, we can add stricter network and command guardrails</li>
</ul>
<p>This does not solve every problem. It just changes the default from &quot;agent on my laptop&quot; to &quot;agent in this project environment&quot;.</p>
<p>For me, that is already a meaningful improvement.</p>
<h2 id="two-services-one-compose-stack">Two services, one Compose stack</h2>
<p>The project was a monorepo with a few connected services. I will call them an API Gateway and a backend service.</p>
<p>The API Gateway proxies requests to the backend service. They also communicate through queue-like flows. In production, that is closer to AWS SQS. Locally, Redis stands in for that piece. The backend service also needs PostgreSQL.</p>
<p>So the local setup had the API Gateway, the backend service, Redis, and PostgreSQL.</p>
<p>The design question was simple to ask and annoying to answer:</p>
<blockquote>
<p>How should devcontainers work in a monorepo with multiple connected services?</p>
</blockquote>
<p>One answer is to create one big devcontainer for everything. I did not like that. It makes the environment heavier, and it does not match how I usually work. Most of the time I am inside one service, even if I need the rest of the stack running nearby.</p>
<p>Another answer is to give each service its own full Docker Compose setup. That also felt wrong. It duplicates configuration and makes cross-service work harder.</p>
<p>The approach that fit this repo was somewhere in the middle.</p>
<p>We kept one root Docker Compose stack. Then each service got its own devcontainer config. The API Gateway devcontainer could start the pieces it needed. The backend devcontainer could start its own dependencies. When I needed to work across the boundary, both devcontainers could exist at the same time.</p>
<p>In practice, the structure looked roughly like this:</p>
<pre><code class="language-text">repo/
  docker-compose.yml
  api-gateway/
    .devcontainer/
      devcontainer.json
  backend/
    .devcontainer/
      devcontainer.json
</code></pre>
<p>The names do not matter much. The important part is that <code>docker-compose.yml</code> stays at the root, while each service owns its own devcontainer entry point.</p>
<p>This is not a universal monorepo pattern. If you have dozens of services, you may need something more deliberate. But for a small set of connected services, this worked well.</p>
<p>The devcontainer did not replace Docker Compose. It reused it.</p>
<p>That distinction made the design much easier to explain. Docker Compose remained the shared runtime model. Devcontainers became the IDE-friendly entry point into that model.</p>
<h2 id="reusing-docker-compose">Reusing Docker Compose</h2>
<p>One thing I liked about this setup is that it did not create a second stack.</p>
<p>The project already had a working <code>docker-compose.yml</code>, so the devcontainer config pointed at it:</p>
<pre><code class="language-json">{
  &quot;dockerComposeFile&quot;: [&quot;../../docker-compose.yml&quot;],
  &quot;service&quot;: &quot;api-gateway&quot;,
  &quot;workspaceFolder&quot;: &quot;/workspace&quot;,
  &quot;shutdownAction&quot;: &quot;none&quot;
}
</code></pre>
<p>This is simplified, but the shape is the point.</p>
<p>The IDE opens inside the selected Compose service. The other services still come from the same Compose file. People who prefer terminal workflows can continue using Compose directly.</p>
<p>One setting was more important than I expected:</p>
<pre><code class="language-json">{
  &quot;shutdownAction&quot;: &quot;none&quot;
}
</code></pre>
<p>This matters when multiple devcontainers share the same Compose stack.</p>
<p>Imagine the API Gateway is open in one IDE window and the backend service is open in another. Closing one window should not stop services that the other window still needs. Without thinking about shutdown behavior, it is easy to make one editor window accidentally own the whole stack.</p>
<p>With <code>shutdownAction: &quot;none&quot;</code>, the devcontainer behaves more like an entry point. It does not try to be the lifecycle manager for everything.</p>
<p>That is a small config detail, but it changes how the setup feels.</p>
<h2 id="keeping-the-container-idle">Keeping the container idle</h2>
<p>Another mistake I wanted to avoid was auto-starting the app as soon as the devcontainer opened.</p>
<p>At first that sounds convenient. Open the container, app starts, done.</p>
<p>In practice, it gets in the way.</p>
<p>I wanted VS Code tasks and launch configs to control the workflow. Sometimes I want watch mode. Sometimes I want debug mode. Sometimes I just want a terminal with dependencies installed. If the container starts the app by default, then a task can start a second copy and hit a port conflict.</p>
<p>So the devcontainer should prepare the environment, then wait.</p>
<p>The setting for that is:</p>
<pre><code class="language-json">{
  &quot;overrideCommand&quot;: true
}
</code></pre>
<p>With this enabled, the container does not run the normal service command from Docker Compose. It stays alive, and the editor tasks decide what happens next.</p>
<p>For debugging Node inside the container, the inspector needs to listen on an address reachable from outside the process namespace:</p>
<pre><code class="language-bash">node --inspect=0.0.0.0:9229 ...
</code></pre>
<p>Binding to <code>localhost</code> inside the container can be confusing because it is localhost from the container&apos;s point of view, not necessarily from the host or debugger&apos;s point of view.</p>
<p>I also learned to be explicit with ports. Docker Compose can publish ports. VS Code can auto-forward ports. Both features are useful, but if they both try to be clever at the same time, debugging becomes harder to reason about.</p>
<p>The pattern I settled on was:</p>
<ul>
<li>Compose defines the important service ports</li>
<li>editor tasks start the app</li>
<li>launch configs attach the debugger</li>
<li>the devcontainer provides the environment</li>
</ul>
<p>That separation made the workflow easier to debug.</p>
<h2 id="moving-readiness-into-compose">Moving readiness into Compose</h2>
<p>One cleanup came from a CodeRabbit review.</p>
<p>There was a startup script that waited for PostgreSQL with a shell loop. You have probably seen this pattern: try to connect, sleep, try again, repeat until the database accepts connections.</p>
<p>It worked. I have written this kind of script many times.</p>
<p>But in this setup, it was in the wrong layer. Docker Compose was already managing PostgreSQL, so Compose should also know when PostgreSQL is ready.</p>
<p>The cleaner version was to use a PostgreSQL healthcheck with <code>pg_isready</code>, then make the backend service wait for it:</p>
<pre><code class="language-yaml">services:
  postgres:
    healthcheck:
      test: pg_isready -U backend -h 127.0.0.1
      interval: 5s

  backend:
    depends_on:
      redis:
        condition: service_started
      postgres:
        condition: service_healthy
</code></pre>
<p>The actual username and service names depend on the project, but the idea is the same: let PostgreSQL report when it can accept connections, and let Compose use that signal.</p>
<p>The important part for the dependent service is this:</p>
<pre><code class="language-yaml">depends_on:
  postgres:
    condition: service_healthy
</code></pre>
<p>This moved the readiness concern closer to the service that owns it.</p>
<p>A post-create script should prepare the workspace. It can install dependencies or create local files. But waiting for infrastructure belongs in the infrastructure config when Compose is already responsible for those services.</p>
<p>CodeRabbit was useful here because it pointed at a rough edge. I still had to decide whether the suggestion fit the architecture. That is the right relationship with AI review tools, at least for me. They are good at making me look twice. They do not get to make the design decision.</p>
<h2 id="running-claude-code-inside-the-devcontainer">Running Claude Code inside the devcontainer</h2>
<p>This was the section I cared about most.</p>
<p>Installing Claude Code was only half the work. The real decision was where it should run.</p>
<p>That meant running it inside the devcontainer as the existing non-root <code>node</code> user, with the terminal starting at the repo root. This mattered because the Claude Code devcontainer docs recommend a non-root user, especially with <code>--dangerously-skip-permissions</code>: if I reduce approval prompts for the agent, I do not also want it running as <code>root</code>, and I do not want to mount more of the host than the project needs.</p>
<p>The repo root part sounds minor, but it matters. Claude Code needs to find project-level guidance and settings. If the terminal opens in the wrong directory, the tool may miss files like <code>CLAUDE.md</code>, or the developer has to remember extra setup steps.</p>
<p>Persistence also needed a bit of care.</p>
<p>A named volume for <code>~/.claude</code> can preserve Claude Code&apos;s directory across container rebuilds. But it does not automatically preserve sibling files such as <code>~/.claude.json</code>.</p>
<p>That distinction matters because tool state and auth can live in different places.</p>
<p>The pattern I liked was:</p>
<ul>
<li>project-owned Claude guidance stays in the repo</li>
<li>developer-owned auth stays outside the repo</li>
<li>auth is mounted through <code>docker-compose.override.yml</code></li>
<li>the mount is read-only where possible</li>
</ul>
<p>For example:</p>
<pre><code class="language-yaml">services:
  api-gateway:
    volumes:
      - ~/.claude.json:/home/node/.claude.json:ro
</code></pre>
<p>The <code>/home/node</code> path in this example is not random. It matches the non-root user inside the container. If the container uses a different non-root user, the mount path should match that user&apos;s home directory instead.</p>
<p>This gives the team a shared way to configure Claude Code for the project without putting personal credentials in Git.</p>
<p>I like this boundary. The repository can describe how the agent should behave in this codebase. The developer can bring their own auth. Those are different concerns, and they should stay separate.</p>
<p>Reference: <a href="https://code.claude.com/docs/en/devcontainer?ref=igkuz.ru">Claude Code devcontainer docs</a>.</p>
<h2 id="putting-vpn-access-in-the-container">Putting VPN access in the container</h2>
<p>The VPN work followed the same logic.</p>
<p>Some workflows need staging services behind a corporate VPN. That does not mean my whole laptop should be on that VPN all day.</p>
<p>So I moved VPN access into the devcontainer path.</p>
<p>The image can include OpenVPN tooling. A local Compose override can add the device, capability, and personal <code>.ovpn</code> file:</p>
<pre><code class="language-yaml">services:
  api-gateway:
    cap_add:
      - NET_ADMIN
    devices:
      - /dev/net/tun:/dev/net/tun
    volumes:
      - ~/vpn/company.ovpn:/etc/openvpn/company.ovpn:ro
</code></pre>
<p>The real <code>.ovpn</code> file is personal and should not be committed. The repo can include a <code>docker-compose.override.yml.example</code> to show the shape of the setup, and each developer can create their own local override.</p>
<p>I also added an editor task to connect the VPN. That made it part of the normal development workflow instead of a separate thing I had to remember.</p>
<p>The rule here is simple:</p>
<blockquote>
<p>Put access where the project needs it.</p>
</blockquote>
<p>The app sometimes needs the VPN. My whole machine does not.</p>
<h2 id="what-i-would-add-next">What I would add next</h2>
<p>The setup is still not as strict as I would like.</p>
<p>The next thing I would look at is network control. Running Claude Code inside a container is better than running it on the host, but an open container network still allows a lot.</p>
<p>A stricter version could allow access to Claude Code, package registries, required internal services, and selected staging endpoints. Everything else could be blocked by default.</p>
<p>That sounds clean on paper. In real projects it can get annoying quickly. Package managers download from more places than you expect. Company networks have weird dependencies. Internal tools call other internal tools. A strict allowlist needs maintenance, or people will route around it.</p>
<p>I would also like better guardrails around destructive actions:</p>
<ul>
<li>deleting large directory trees</li>
<li>force-pushing branches</li>
<li>changing sensitive config</li>
<li>installing unexpected packages</li>
</ul>
<p>Some of this could be handled with hooks. Some of it needs team policy. Some of it may be too fragile to treat as security.</p>
<p>I am fine with that. Guardrails do not have to be perfect to be useful. They just need to catch enough mistakes to be worth the friction.</p>
<h2 id="the-result">The result</h2>
<p>This work started as devcontainer setup, but that is not really what it was about.</p>
<p>It was about making the development environment fit the way we now work.</p>
<p>After the changes, IDE users get a native devcontainer workflow. Terminal users can still use Docker Compose. The two connected services can run together. Claude Code can work with fewer approval prompts, but inside a project environment instead of directly on the host. VPN access can be scoped to the container. The setup is also documented in the project instead of living only in someone&apos;s head.</p>
<p>That feels like progress.</p>
<p>It does not remove all risk. It does not mean this exact design fits every repo. And it definitely does not make AI agents magically safe.</p>
<p>But I am much more comfortable giving Claude Code room to work inside a constrained project environment than on my laptop.</p>
<p>That is the practical tradeoff I wanted: fewer interruptions, more useful autonomy, and a smaller blast radius when something goes wrong.</p>
<h2 id="references">References</h2>
<p>These resources might be inspirational for you as they were for me. Specifically I want to mention the video by Dan Guido about his approach to transform the company to AI native. It&apos;s a top to bottom action, but you can learn a lot on hands on actions.</p>
<ul>
<li><a href="https://containers.dev/?ref=igkuz.ru">Dev Container Specification</a></li>
<li><a href="https://containers.dev/implementors/json_reference/?ref=igkuz.ru">Dev Container JSON reference</a></li>
<li><a href="https://code.visualstudio.com/docs/devcontainers/create-dev-container?ref=igkuz.ru">VS Code Dev Containers documentation</a></li>
<li><a href="https://code.visualstudio.com/remote/advancedcontainers/connect-multiple-containers?ref=igkuz.ru">VS Code documentation on connecting to multiple containers</a></li>
<li><a href="https://code.claude.com/docs/en/devcontainer?ref=igkuz.ru">Claude Code devcontainer documentation</a></li>
<li><a href="https://github.com/trailofbits/claude-code-config?ref=igkuz.ru">Trail of Bits Claude Code config</a></li>
<li><a href="https://github.com/trailofbits/claude-code-devcontainer?ref=igkuz.ru">Trail of Bits Claude Code devcontainer</a></li>
<li><a href="https://www.youtube.com/watch?v=kgwvAyF7qsA&amp;ref=igkuz.ru">Dan Guido&apos;s talk on rebuilding Trail of Bits around AI</a></li>
<li><a href="https://evilmartians.com/chronicles/ruby-on-whales-docker-for-ruby-rails-development?ref=igkuz.ru">Evil Martians: Ruby on Whales: Docker for Ruby &amp; Rails development</a></li>
</ul>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[TIL: Using MacOS tags for better search]]></title><description><![CDATA[<p>Preparing for visas is a nightmare for a normal person and might be a sweetspot for those who has OCD. My docs are messy, but at least I keep them in one place in the cloud. I come up with a certain structure like <code>Docs/Igor/smth/</code> etc. Clicking every</p>]]></description><link>https://igkuz.ru/til/</link><guid isPermaLink="false">698f4cf84e9347710787e576</guid><category><![CDATA[Today I learned]]></category><dc:creator><![CDATA[Igor Kuznetsov]]></dc:creator><pubDate>Fri, 13 Feb 2026 16:24:11 GMT</pubDate><content:encoded><![CDATA[<p>Preparing for visas is a nightmare for a normal person and might be a sweetspot for those who has OCD. My docs are messy, but at least I keep them in one place in the cloud. I come up with a certain structure like <code>Docs/Igor/smth/</code> etc. Clicking every time to multiple folders to open them and search for files was a normal routine, because I didn&apos;t pay to much attention to it.</p><p>Yesterday, looking for my son&apos;s passport details I finally realized how time consuming it is and thought &#x2013; this is it &#x1F603;</p><p>After short research I came to a structure recommended by ChatGTP</p><pre><code class="language-bash">01_Personal/
	IDs/
    	Igor/
        	Passports/
            Residency_&lt;country-code&gt;/
        Family/
        	&lt;wife-name&gt;/
            	Passports/
            	Residency_&lt;country-code&gt;/
            &lt;son-name/&gt;
            	Passports/
            	Residency_&lt;country-code&gt;/</code></pre><p>Each file has certain tags: <code>legal</code> , <code>me</code> , <code>family</code> , <code>ru</code> , <code>es</code> , <code>travel</code> , <code>freq</code>.</p><p>A bunch of smart folders which helps access the most frequently accessed documents and couple of Alfred keywords (which I&apos;m still learning) following this tutorial: <a href="https://www.alfredapp.com/blog/tips-and-tricks/3-ways-to-use-osx-tags-for-better-search/?ref=igkuz.ru">https://www.alfredapp.com/blog/tips-and-tricks/3-ways-to-use-osx-tags-for-better-search/</a></p>]]></content:encoded></item><item><title><![CDATA[TIL: How to configure CloudFront Functions for SPA]]></title><description><![CDATA[<p>Last week, we audited parts of our old infrastructure and found many outdated configurations. They were working, but could be doing better.</p><p>We had a strange chain of CloudFront &#x2192; Nginx &#x2192; S3 bucket. Nginx was doing some complex redirects that were necessary at that time, as the single-page application</p>]]></description><link>https://igkuz.ru/how-to-configure-cloudfront-functions-for-spa/</link><guid isPermaLink="false">693c42b64e9347710787e4c1</guid><category><![CDATA[Today I learned]]></category><dc:creator><![CDATA[Igor Kuznetsov]]></dc:creator><pubDate>Fri, 12 Dec 2025 20:31:04 GMT</pubDate><media:content url="https://images.unsplash.com/photo-1492573637402-25691cd9eac2?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDIwfHxmYXN0fGVufDB8fHx8MTc2NTU3MTQyNnww&amp;ixlib=rb-4.1.0&amp;q=80&amp;w=2000" medium="image"/><content:encoded><![CDATA[<img src="https://images.unsplash.com/photo-1492573637402-25691cd9eac2?crop=entropy&amp;cs=tinysrgb&amp;fit=max&amp;fm=jpg&amp;ixid=M3wxMTc3M3wwfDF8c2VhcmNofDIwfHxmYXN0fGVufDB8fHx8MTc2NTU3MTQyNnww&amp;ixlib=rb-4.1.0&amp;q=80&amp;w=2000" alt="TIL: How to configure CloudFront Functions for SPA"><p>Last week, we audited parts of our old infrastructure and found many outdated configurations. They were working, but could be doing better.</p><p>We had a strange chain of CloudFront &#x2192; Nginx &#x2192; S3 bucket. Nginx was doing some complex redirects that were necessary at that time, as the single-page application was gradually covering old pages. On top of this chain, I found an AWS Lambda attached to the Viewer Response. It was also doing some redirects. Yeah, when people leave the company, they take some knowledge with them, and you need to be very good at technical handoff to keep this knowledge.</p><p>Since 2020, when this part of the infrastructure was deployed, CloudFront has released several interesting features.</p><h4 id="feature-1-cloudfront-functions">Feature 1. CloudFront Functions</h4><p>This is exactly what you need to do simple redirects or HTTP header modifications.</p><figure class="kg-card kg-bookmark-card"><a class="kg-bookmark-container" href="https://aws.amazon.com/blogs/aws/introducing-cloudfront-functions-run-your-code-at-the-edge-with-low-latency-at-any-scale/?ref=igkuz.ru"><div class="kg-bookmark-content"><div class="kg-bookmark-title">Introducing CloudFront Functions &#x2013; Run Your Code at the Edge with Low Latency at Any Scale | Amazon Web Services</div><div class="kg-bookmark-description">With Amazon CloudFront, you can securely deliver data, videos, applications, and APIs to your customers globally with low latency and high transfer speeds. To offer a customized experience and the lowest possible latency, many modern applications execute some form of logic at the edge. The use cases&#x2026;</div><div class="kg-bookmark-metadata"><img class="kg-bookmark-icon" src="https://a0.awsstatic.com/main/images/site/touch-icon-ipad-144-smile.png" alt="TIL: How to configure CloudFront Functions for SPA"><span class="kg-bookmark-author">Amazon Web Services</span><span class="kg-bookmark-publisher">Danilo Poccia</span></div></div><div class="kg-bookmark-thumbnail"><img src="https://d2908q01vomqb2.cloudfront.net/da4b9237bacccdf19c0760cab7aec4a8359010b0/2021/04/01/cloudfront-functions-where-1214x630.png" alt="TIL: How to configure CloudFront Functions for SPA"></div></a></figure><p>Single page applications do the virtual routing, meaning that the JS app handles all the routing and the actual page files do not exist on disk. So all you need is to rewrite all requests like <code>www.example.com/auth/login/</code> to <code>s3://your-bucket-name/index.html</code>, and the JS app will load and handle the rest in the browser.</p><p>Our app lives in a subroute, so the CloudFront function can look like this</p><pre><code class="language-javascript">function handler(event) {
    var request = event.request;
    var uri = request.uri;
    
    // Check if URI is missing an extension (like .js, .css, .html)
    if (!uri.includes(&apos;.&apos;)) {
        // Rewrite to SPA root index.html
        request.uri = &apos;/index.html&apos;; 
    }
    
    return request;
}</code></pre><p>It rewrites all requests to <code>index.html</code> in the root of the bucket. The important thing here is to decide what caching strategy you want for this file. You need to set it at upload time.</p><p>The recommended setup is to always return a fresh version of <code>index.html</code>, meaning you will have <code>Cache-Control: max-age=0</code>. However, there is an awesome feature that I didn&#x2019;t know about: <code>s-maxage</code>.</p><figure class="kg-card kg-bookmark-card"><a class="kg-bookmark-container" href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Cache-Control?ref=igkuz.ru#s-maxage"><div class="kg-bookmark-content"><div class="kg-bookmark-title">Cache-Control header - HTTP | MDN</div><div class="kg-bookmark-description">The HTTP Cache-Control header holds directives (instructions) in both requests and responses that control caching in browsers and shared caches (e.g., Proxies, CDNs).</div><div class="kg-bookmark-metadata"><img class="kg-bookmark-icon" src="https://developer.mozilla.org/favicon.ico" alt="TIL: How to configure CloudFront Functions for SPA"><span class="kg-bookmark-author">MDN</span></div></div></a></figure><p>Cache-Control metadata for <code>index.html</code> can be: <code>public, max-age=0, s-maxage=86400, must-revalidate</code></p><p>CloudFront respects this and can return a cached version for some time while doing a refresh request in the background. The user&#x2019;s browser won&#x2019;t cache the file because it respects the <code>max-age</code> directive. You need to be careful with how you deploy the app and execute invalidation requests in order to keep the previous <code>index.html</code> content available for some time.</p><h4 id="feature-2-cloudfront-key-value-store-kvs">Feature 2. CloudFront Key Value Store (KVS)</h4><p>Nginx had some rules to easily enable or disable maintenance mode. CloudFront KVS can do this for you. Both Functions and Key Value Store are designed to be blazingly fast and have a microseconds-level budget, so they will not affect your latency as much as you might think.</p><figure class="kg-card kg-bookmark-card"><a class="kg-bookmark-container" href="https://aws.amazon.com/blogs/aws/introducing-amazon-cloudfront-keyvaluestore-a-low-latency-datastore-for-cloudfront-functions/?ref=igkuz.ru"><div class="kg-bookmark-content"><div class="kg-bookmark-title">Introducing Amazon CloudFront KeyValueStore: A low-latency datastore for CloudFront Functions | Amazon Web Services</div><div class="kg-bookmark-description">December 12, 2023: Post updated to clarify that when a CloudFront function changes the uri value, it doesn&#x2019;t change the cache behavior for the request or the origin that an origin request is sent to. Amazon CloudFront allows you to securely deliver static and dynamic content with low latency and hig&#x2026;</div><div class="kg-bookmark-metadata"><img class="kg-bookmark-icon" src="https://a0.awsstatic.com/main/images/site/touch-icon-ipad-144-smile.png" alt="TIL: How to configure CloudFront Functions for SPA"><span class="kg-bookmark-author">Amazon Web Services</span><span class="kg-bookmark-publisher">Danilo Poccia</span></div></div><div class="kg-bookmark-thumbnail"><img src="https://d2908q01vomqb2.cloudfront.net/da4b9237bacccdf19c0760cab7aec4a8359010b0/2023/12/12/cloudfront-kvs-architecture-2-1260x628.png" alt="TIL: How to configure CloudFront Functions for SPA"></div></a></figure><figure class="kg-card kg-bookmark-card"><a class="kg-bookmark-container" href="https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/kvs-with-functions.html?ref=igkuz.ru"><div class="kg-bookmark-content"><div class="kg-bookmark-title">Amazon CloudFront KeyValueStore - Amazon CloudFront</div><div class="kg-bookmark-description">Learn how to work with key value stores and key-value pairs that you use with CloudFront Functions.</div><div class="kg-bookmark-metadata"><img class="kg-bookmark-icon" src="https://docs.aws.amazon.com/assets/images/favicon.ico" alt="TIL: How to configure CloudFront Functions for SPA"><span class="kg-bookmark-author">Amazon CloudFront</span></div></div></a></figure><p>In the Use Cases section, AWS docs mention that it is useful for A/B testing, rewrites, and handling auth-based locations. Maintenance, broadly speaking, is just a subset of A/B testing. So you can easily add a variable like <code>maintenance-mode</code> and read it on each request. Yes, it comes at a certain price, so be mindful of the number of requests coming to your app.</p><p>So your function can look like this</p><pre><code class="language-javascript">import cf from &apos;cloudfront&apos;;

const kvsId = &apos;&lt;KEY_VALUE_STORE_ID&gt;&apos;;

// If the KeyValueStore isn&apos;t associated with this function, creating the handle can fail.
// In that case we fall back to behaving as if maintenance mode is off.
let kvsHandle = null;
try {
  kvsHandle = cf.kvs(kvsId);
} catch (e) {
  kvsHandle = null;
}

async function handler(event) {
  const request = event.request;
  const uri = request.uri || &apos;/&apos;;

  // Rule 1: Requests to &quot;static files&quot; (last path segment contains an extension) pass through unchanged,
  // even if maintenance mode is enabled.
  const lastSegment = uri.split(&apos;/&apos;).pop() || &apos;&apos;;
  const hasExtension = lastSegment.includes(&apos;.&apos;) &amp;&amp; !lastSegment.endsWith(&apos;.&apos;);
  if (hasExtension) {
    return request;
  }

  // Rule 2: Check maintenance flag from CloudFront KeyValueStore (only for non-static routes)
  const key = &apos;maintenance-mode&apos;;
  let maintenanceOn = false;

  if (kvsHandle) {
    try {
      const raw = await kvsHandle.get(key);
      // Not sure how the key will be stored in kvs, need to check
      maintenanceOn = String(raw).trim().toLowerCase() === &apos;true&apos;;
    } catch (err) {
      // If there&apos;s an error, treat it as maintenance off (per your requirement)
      console.log(`KVS lookup failed for ${key}: ${err}`);
      maintenanceOn = false;
    }
  }

  // Rule 3: Rewrite to index.html by default, or maintenance page if flag is true
  request.uri = maintenanceOn ? &apos;/maintenance/index.html&apos; : &apos;/index.html&apos;;

  return request;
}

export { handler };</code></pre><p>Associate this function with Viewer Request and that&apos;s it.</p>]]></content:encoded></item><item><title><![CDATA[Managing Unicorn & Puma web servers with systemd]]></title><description><![CDATA[In production, you have to work with service crashes and auto restarts. Systemd can handle that for you. Unicorn and Puma systemd service.]]></description><link>https://igkuz.ru/managing-unicorn-puma-web-servers-with-systemd/</link><guid isPermaLink="false">5e9209026d9007355d8bde87</guid><category><![CDATA[devops]]></category><category><![CDATA[Systemd]]></category><category><![CDATA[Ruby]]></category><category><![CDATA[Puma]]></category><category><![CDATA[unicorn]]></category><category><![CDATA[Web Server]]></category><dc:creator><![CDATA[Igor Kuznetsov]]></dc:creator><pubDate>Mon, 16 Sep 2019 07:00:00 GMT</pubDate><media:content url="https://igkuz.ru/content/images/2020/04/systemd-unicorn-puma-2.png" medium="image"/><content:encoded><![CDATA[<img src="https://igkuz.ru/content/images/2020/04/systemd-unicorn-puma-2.png" alt="Managing Unicorn &amp; Puma web servers with&#xA0;systemd"><p>In production environment, you have to deal with service crashes and auto restarts, and there are plenty of tools to that end&#x2014; supervisord, monit etc. Having lots of projects, we try to use standard utilities that come with distros, Ubuntu in our case.</p><p>Standard Ubuntu init system is <a href="https://www.freedesktop.org/software/systemd/man/systemd.service.html?ref=igkuz.ru" rel="noopener">Systemd</a>, definitely one of the most famous and widely used tools. It&#x2019;s a security standard to run apps under non-privileged users, and systemd offers a solution in this case.</p><figure class="kg-card kg-image-card"><img src="https://cdn-images-1.medium.com/max/800/0*DUaAH_yQIZ0ZHgn6.png" class="kg-image" alt="Managing Unicorn &amp; Puma web servers with&#xA0;systemd" loading="lazy"></figure><p>Our initial setup is Ruby via RVM and Unicorn/Puma running simple Rack application.</p><figure class="kg-card kg-image-card"><img src="https://cdn-images-1.medium.com/max/800/0*_6koVm1d4Eq15DYz.png" class="kg-image" alt="Managing Unicorn &amp; Puma web servers with&#xA0;systemd" loading="lazy"></figure><p>Important notice, I don&apos;t provide Docker files with examples as systemd won&apos;t succeed in a non-privileged mode in Docker, so I advise you to test this in a separate virtual machine. You can find more on this case on askubuntu and Docker docs. For macOS, you can use LXD or multipass to spin up Ubuntu VM. LXD setup can be tricky, so for this project, I&apos;ve prepared a cloud-init file that can be used as a multipass entrypoint.</p><figure class="kg-card kg-code-card"><pre><code class="language-yaml">packages:
  - build-essential
  - bison
  - libreadline6
  - libreadline6-dev
  - curl
  - git-core
  - zlib1g-dev
  - libssl-dev
  - libyaml-dev
  - libsqlite3-dev
  - sqlite3
  - libxml2-dev
  - libxslt-dev
  - autoconf
  - ncurses-dev

runcmd:
  - gpg --keyserver hkp://pool.sks-keyservers.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB
  - &apos;\curl -sSL https://get.rvm.io | bash -s stable --ruby=ruby-2.5.3 --gems=bundler&apos;
  - mkdir /apps
  - useradd -d /apps/awesomeapp -m -s /bin/bash -G rvm awesomeapp
view raw
</code></pre><figcaption><a href="https://gist.github.com/igkuz/2960bbdbd481744ab26d84140645e179?ref=igkuz.ru#file-init-yml">init.yml</a></figcaption></figure><pre><code class="language-bash">multipass launch -n sysd -c 1 -m 2g --cloud-init init.yml xenial</code></pre><p>Based on Xenial, because we made an infrastructure upgrade from 12.04 to 16.04 LTS in 2017, so it&#x2019;s our standard for this &amp; next year.</p><figure class="kg-card kg-image-card"><img src="https://cdn-images-1.medium.com/max/800/0*2E1-sB2zARv_-kn_" class="kg-image" alt="Managing Unicorn &amp; Puma web servers with&#xA0;systemd" loading="lazy"></figure><p>Assume we have a non-privileged user <code>awesomeapp</code> with home directory <code>/apps/awesomeapp</code> and shell <code>/bin/bash</code>. App root <code>/apps/awesomeapp/awesomeapp-git</code>.</p><p>Let&#x2019;s prepare the directory structure for systemd files:</p><pre><code class="language-bash">mkdir -p /apps/awesomeapp/.config/systemd/user</code></pre><p>Create <code>unicorn.service</code> . All files for the application can be found at <a href="https://github.com/igkuz/unicorn-puma-systemd?ref=igkuz.ru" rel="noopener">sample repo on my Github</a>.</p><figure class="kg-card kg-code-card"><pre><code class="language-bash">[Unit]
Description=Unicorn service
After=network.target

[Service]
Type=forking
Environment=RAILS_ENV=production
WorkingDirectory=/apps/awesomeapp/awesomeapp-git

PIDFile=/apps/awesomeapp/awesomeapp-git/tmp/pids/unicorn.pid
ExecStart=/bin/bash -l -c &apos;bundle exec unicorn -c config/unicorn.rb -D&apos;
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
KillSignal=SIGQUIT
Restart=on-failure
SyslogIdentifier=awesomeapp-unicorn

[Install]
WantedBy=default.target</code></pre><figcaption><a href="https://gist.github.com/igkuz/681f8904ce35d1a0dffd35073a1c1f66?ref=igkuz.ru#file-unicorn-service">unicorn.service</a></figcaption></figure><p>Reload <code>systemd</code> daemon:</p><pre><code class="language-bash">awesomeapp@sysd:~$ systemctl --user daemon-reload
Failed to connect to bus: No such file or directory</code></pre><p>There is a discussion about this error on <a href="https://answers.launchpad.net/ubuntu/+source/systemd/+question/287454?ref=igkuz.ru" rel="noopener">launchpad</a>. To fix it, just add to <code>/apps/awesomeapp/.profile</code>.</p><pre><code class="language-bash">export XDG_RUNTIME_DIR=/run/user/`id -u`</code></pre><p>After that, from root or your sudo user enable <a href="https://www.freedesktop.org/software/systemd/man/loginctl.html?ref=igkuz.ru#enable-linger%20USER%E2%80%A6" rel="noopener">user lingering</a>:</p><pre><code class="language-bash">sudo loginctl enable-linger awesomeapp</code></pre><p>check that it works:</p><pre><code class="language-bash">loginctl user-status awesomeapp</code></pre><p>You should see smth like this:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://cdn-images-1.medium.com/max/800/1*YZ8sc0_EORBqGM-xDLQ4Wg.png" class="kg-image" alt="Managing Unicorn &amp; Puma web servers with&#xA0;systemd" loading="lazy"><figcaption>User status after lingering is&#xA0;enabled.</figcaption></figure><p>Login back to the user and reload the daemon:</p><pre><code class="language-bash">sudo -iu awesomeapp
systemctl --user daemon-reload</code></pre><p><code>systemctl</code> command under app user without sudo, it&#x2019;s not a mistake. App user can use it freely, so, dev team can maintain service files easily without operations team involved.</p><p>Check the status:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://cdn-images-1.medium.com/max/800/1*JuX604GjH1zM97s-Oh_5-A.png" class="kg-image" alt="Managing Unicorn &amp; Puma web servers with&#xA0;systemd" loading="lazy"><figcaption>Checking Unicorn systemd service&#xA0;status</figcaption></figure><p>It&#x2019;s inactive, not running and disabled. It means that it won&#x2019;t start up after boot. For example, you have 1..N app machines, and some of them can go down for system upgrades or just because of a crash, so we need the app running after reboot.</p><pre><code class="language-bash">systemctl --user enable unicorn</code></pre><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://cdn-images-1.medium.com/max/800/1*0ewjFasd16uTWQ5HRJM8AQ.png" class="kg-image" alt="Managing Unicorn &amp; Puma web servers with&#xA0;systemd" loading="lazy"><figcaption>Enabling Unicorn systemd&#xA0;service</figcaption></figure><p>Let&#x2019;s give it a try:</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://cdn-images-1.medium.com/max/800/1*oXmOvdCT56DtqkcQEQQ2fQ.png" class="kg-image" alt="Managing Unicorn &amp; Puma web servers with&#xA0;systemd" loading="lazy"><figcaption>Starting and checking status for Unicorn systemd&#xA0;service</figcaption></figure><p>Unicorn master process and 2 worker process, as we configured.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://cdn-images-1.medium.com/max/800/1*sRqmSpqNlrfO3MDWtPfHcw.png" class="kg-image" alt="Managing Unicorn &amp; Puma web servers with&#xA0;systemd" loading="lazy"><figcaption>Checking app response for Unicorn systemd&#xA0;service</figcaption></figure><p>Let&#x2019;s do the same for Puma, standard Rails web server. Puma.service file:</p><figure class="kg-card kg-code-card"><pre><code class="language-bash">[Unit]
Description=Puma service
After=network.target

[Service]
Type=forking
Environment=RAILS_ENV=production
WorkingDirectory=/apps/awesomeapp/awesomeapp-git

PIDFile=/apps/awesomeapp/awesomeapp-git/tmp/pids/puma.pid
ExecStart=/bin/bash -l -c &apos;bundle exec puma -C config/puma.rb&apos;
ExecStop=/bin/bash -l -c &apos;bundle exec pumactl -F config/puma.rb stop&apos;
ExecReload=/bin/bash -l -c &apos;bundle exec pumactl -F config/puma.rb phased-restart&apos;
Restart=on-failure

SyslogIdentifier=awesomeapp-puma

[Install]
WantedBy=default.target</code></pre><figcaption><a href="https://gist.github.com/igkuz/6b104a178bae8ee5a307959b035116a4?ref=igkuz.ru#file-puma-service">puma.service</a></figcaption></figure><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://cdn-images-1.medium.com/max/800/1*JlZou4xrG7HtZq1I08RLgQ.png" class="kg-image" alt="Managing Unicorn &amp; Puma web servers with&#xA0;systemd" loading="lazy"><figcaption>Puma systemd service run and&#xA0;check</figcaption></figure><p>Now you can reboot VM and check that everything up and running.</p><p>All commands with comments.</p><p>Unicorn:</p><pre><code class="language-bash"># check unicorn.service status
systemctl --user status unicorn

# start unicorn.service
systemctl --user start unicorn

# start unicorn.service on VM boot
systemctl --user enable unicorn

# disable starting unicorn.service on VM boot
systemctl --user disable unicorn

# restart unicorn.service
systemctl --user restart unicorn

# graceful restart unicorn.service
systemctl --user reload unicorn

# stop unicorn.service
systemctl --user stop unicorn</code></pre><p>Puma:</p><pre><code class="language-bash"># check puma.service status
systemctl --user status puma

# start puma.service
systemctl --user start puma

# start puma.service on VM boot
systemctl --user enable puma

# disable starting puma.service on VM boot
systemctl --user disable puma

# restart puma.service
systemctl --user restart puma

# graceful restart puma.service
systemctl --user reload puma

# stop puma.service
systemctl --user stop puma</code></pre><p>That&#x2019;s it for today. Puma and Unicorn configs are for the sample app, for production purposes, you definitely must adopt to needs and load.</p>]]></content:encoded></item><item><title><![CDATA[Ruby retry/scheduled tasks with Dead Letter Exchange in RabbitMQ]]></title><description><![CDATA[Ruby scheduled tasks with dead letter exchange in RabbitMQ, using bunny gem.]]></description><link>https://igkuz.ru/ruby-retry-scheduled-tasks-with-dead-letter-exchange-in-rabbitmq/</link><guid isPermaLink="false">5e9209026d9007355d8bde84</guid><category><![CDATA[Ruby]]></category><category><![CDATA[RabbitMQ]]></category><category><![CDATA[Scheduled Tasks]]></category><category><![CDATA[Docker]]></category><dc:creator><![CDATA[Igor Kuznetsov]]></dc:creator><pubDate>Wed, 13 Mar 2019 07:00:00 GMT</pubDate><media:content url="https://igkuz.ru/content/images/2020/04/ruby-rabbitmq-dlx-2.jpg" medium="image"/><content:encoded><![CDATA[<img src="https://igkuz.ru/content/images/2020/04/ruby-rabbitmq-dlx-2.jpg" alt="Ruby retry/scheduled tasks with Dead Letter Exchange in RabbitMQ"><p>There is a project where I need outgoing requests rate limiting. This is the opposite case for the more common situation when you develop API and rate limit clients incoming requests.</p><p>With outgoing requests, you need to queue them and give a slot only for some. We&#x2019;re collecting analytics for web pages. As we collect data only from public sources, we try not to be banned by firewalls or DDoS protection services. Making 1 request per second for content sites is more than enough, as there is no need for speed.</p><p>RabbitMQ Cluster is part of our infrastructure and the default queuing solution. Unfortunately, RabbitMQ doesn&#x2019;t come with native support for delayed or scheduled messages. Fortunately, RabbitMQ has Dead Letter Exchanges (DLX), which allows us to simulate message scheduling.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://cdn-images-1.medium.com/max/800/1*N4YDDxr5MvhQbiYsWmfbNA.png" class="kg-image" alt="Ruby retry/scheduled tasks with Dead Letter Exchange in RabbitMQ" loading="lazy"><figcaption>RabbitMQ dead letter exchange scheme</figcaption></figure><p>I&#x2019;m going to explain how it works and what do we need to build.</p><p>When you create a queue (Q1) bound to exchange (X), you can also specify the Dead Letter Exchange (DLX) to route rejected messages. This process is automatically handled by RMQ. Another queue (Q2) bound to DLX to consume the messages after they&#x2019;ve been rejected from original (Q1).<br>And to deliver messages automatically back we can set original exchange as dead letter exchange to the (Q2).<br>Look at the image.</p><p>Sounds a little bit complex, but it&#x2019;s cool that we need only 1 consumer, all other stuff will be handled by RabbitMQ.</p><h4 id="how-to">How to?</h4><ol><li>Create TargetQueue bound to TargetExchange:<br>&#x2013; set Dead Letter Exchange to RetryExchange</li><li>Create RetryQueue bound to RetryExchange:<br>&#x2013; set Dead Letter Exchange to TargetExchange<br>&#x2013; set Message Time To Live (TTL) to the desired time (1 minute for example)</li></ol><p>Steps to test the solution:</p><ol><li>Publish message to TargetQueue</li><li>Consumer gets the message and tries to process it</li><li>Process fails, consumer rejects the message</li><li>Rabbit routes the message with the same routing key to RetryExchange</li><li>Message moves to RetryQueue, sits for 90 seconds</li><li>When message expires, it is resent to TargetExchange and routed to TargetQueue</li></ol><h4 id="let-s-proceed-to-code">Let&#x2019;s proceed to code</h4><p>In Ruby, there are two popular solutions for RabbitMQ. <a href="https://github.com/ruby-amqp/bunny?ref=igkuz.ru" rel="noopener">Bunny</a> and <a href="https://github.com/jondot/sneakers?ref=igkuz.ru" rel="noopener">Sneakers</a>, which is a really nice abstraction for Bunny. For this post, I choose Bunny as it can show some low-level operations. For my next post, where the whole project is going to be described, I&#x2019;ll show the &#x201C;Sneakers&#x201D; way.</p><p>As always, the final solution can be found in <a href="https://github.com/igkuz/rate-limit-with-rmq-sample?ref=igkuz.ru" rel="noopener">my repository on GitHub</a>.</p><p>Create a Gemfile and install all necessary stuff.</p><figure class="kg-card kg-code-card"><pre><code class="language-ruby">source &apos;https://rubygems.org&apos;

gem &apos;bunny&apos;
gem &apos;redis&apos;</code></pre><figcaption><a href="https://gist.github.com/igkuz/2e0170d7b62f560c8a7f9ed602d73b57?ref=igkuz.ru#file-gemfile">Gemfile</a></figcaption></figure><p>Create publisher, it only publishes a message with routing key to an exchange.</p><figure class="kg-card kg-code-card"><pre><code class="language-ruby">#!/usr/bin/env ruby
# encoding utf-8

require &apos;bunny&apos;
require &apos;json&apos;
STDOUT.sync = true

conn = Bunny.new(host: &apos;rmq&apos;, user: &apos;guest&apos;, pass: &apos;guest&apos;)
conn.start

ch = conn.create_channel
x = ch.exchange(&apos;work.exchange&apos;)

(1..10).each do |i|
  x.publish(
      {id: i, text: &quot;I&apos;m message #{i}&quot;}.to_json,
      routing_key: &apos;work.queue&apos;,
      headers: {
        content_type: &apos;application/json&apos;
      }
    )
end
conn.close</code></pre><figcaption><a href="https://gist.github.com/igkuz/8cfe95d4e6d3407d56d9cd51ae9fb80d?ref=igkuz.ru#file-publisher-rb">publisher.rb</a></figcaption></figure><p>Create consumer, it will get messages, process them, try to get the slot for the request and whet it fails, reject them.</p><figure class="kg-card kg-code-card"><pre><code class="language-ruby">#!/usr/bin/env ruby
# encoding utf-8

require &apos;bunny&apos;
require &apos;logger&apos;
require &apos;redis&apos;

logger = Logger.new(STDOUT)
STDOUT.sync = true

conn = Bunny.new(host: &apos;rmq&apos;, user: &apos;guest&apos;, pass: &apos;guest&apos;)
conn.start

ch = conn.create_channel
q = ch.queue(&apos;work.queue&apos;, arguments: { :&apos;x-dead-letter-exchange&apos; =&gt; &apos;retry.exchange&apos; })

Redis.current = Redis.new(host: &apos;redis&apos;)

# `block: true` is only for presentation purposes
# it blocks the main thread, do not use it in production
q.subscribe(manual_ack: true, block: true) do |delivery_info, properties, payload|
  logger.info &quot;Message received with payload: #{payload}&quot;
  key = &quot;slot:#{Time.now.utc.sec}&quot;
  slot = Redis.current.get(key)
  logger.info &quot;Slot value: #{slot}&quot;
  if !slot || slot.to_i &lt; 1
    logger.info &quot;Slot acquired, writing to Redis&quot;
    result = Redis.current.multi do |multi|
      multi.set(key, 1)
      multi.expire(key, 1)
    end
    logger.info &quot;Slot acquired, finished writing to Redis with result: #{result}&quot;
    ch.ack(delivery_info.delivery_tag)
    logger.info &quot;Message acked&quot;
  else
    # reject without requeue
    ch.reject(delivery_info.delivery_tag)
    logger.info &quot;Message rejected&quot;
  end
end

conn.close</code></pre><figcaption><a href="https://gist.github.com/igkuz/3e43e5a80362c5fbbdabce27354c2821?ref=igkuz.ru#file-consumer-rb">consumer.rb</a></figcaption></figure><p>Create the starting point for our applications. We create exchanges and queues in it.</p><figure class="kg-card kg-code-card"><pre><code class="language-ruby">#!/usr/bin/env ruby
# encoding utf-8

require &apos;bunny&apos;

STDOUT.sync = true

conn = Bunny.new(host: &apos;rmq&apos;, user: &apos;guest&apos;, pass: &apos;guest&apos;)
conn.start

ch = conn.create_channel
x = ch.direct(&apos;work.exchange&apos;)
dlx = ch.direct(&apos;retry.exchange&apos;)

target_queue = ch.queue(&apos;work.queue&apos;, arguments: {
  :&apos;x-dead-letter-exchange&apos; =&gt; &apos;retry.exchange&apos;
}).bind(x, routing_key: &apos;work.queue&apos;)

retry_queue = ch.queue(&apos;retry.queue&apos;, arguments: {
  :&apos;x-dead-letter-exchange&apos; =&gt; &apos;work.exchange&apos;,
  :&apos;x-message-ttl&apos; =&gt; 60000
}).bind(dlx, routing_key: &apos;work.queue&apos;)

conn.close</code></pre><figcaption><a href="https://gist.github.com/igkuz/4040cf79168f62761a1b6a68ad6250d6?ref=igkuz.ru#file-start-rb">start.rb</a></figcaption></figure><p>For rate-limiting, I prefer <a href="https://redislabs.com/redis-best-practices/basic-rate-limiting/?ref=igkuz.ru" rel="noopener nofollow">Redis way</a>. It is one of the most popular solutions for in-memory databases. I think a lot of ruby projects use Sidekiq, so you definitely have Redis at your infrastructure. It can be tricky to develop a rate-limiting without Redis or Memcached, but still, there is a way. If you feel strong and enjoy inventing the bicycles, code it by yourself. For example &#x2014; <a href="https://en.wikipedia.org/wiki/Token_bucket?ref=igkuz.ru" rel="noopener nofollow">Token buckets</a>.</p><h2 id="app-in-action">App in action</h2><pre><code class="language-bash">docker-compose run app ./start</code></pre><p>Take a look at RabbitMQ management page. It is available at http://localhost:8080.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://cdn-images-1.medium.com/max/800/1*QPJwZ3CkxSDyjZPMAh2CKQ.png" class="kg-image" alt="Ruby retry/scheduled tasks with Dead Letter Exchange in RabbitMQ" loading="lazy"><figcaption>Created RabbitMQ exchanges</figcaption></figure><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://cdn-images-1.medium.com/max/800/1*2jLy6UTJrSGpO497oTWBXQ.png" class="kg-image" alt="Ruby retry/scheduled tasks with Dead Letter Exchange in RabbitMQ" loading="lazy"><figcaption>Created RabbitMQ&#xA0;queues</figcaption></figure><pre><code class="language-bash">docker-compose run app ./publisher</code></pre><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://cdn-images-1.medium.com/max/800/1*W9uxR2Vr0z_emHBXlPhlZw.png" class="kg-image" alt="Ruby retry/scheduled tasks with Dead Letter Exchange in RabbitMQ" loading="lazy"><figcaption>10 messages published</figcaption></figure><p>As we can see all messages are published, but as there are no consumers, all they sit in a queue.</p><pre><code class="language-bash">docker-compose run app ./consumer</code></pre><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://cdn-images-1.medium.com/max/800/1*A13sUbBr7_1qnPJ-_MSUOQ.png" class="kg-image" alt="Ruby retry/scheduled tasks with Dead Letter Exchange in RabbitMQ" loading="lazy"><figcaption>Messages processed by&#xA0;consumer</figcaption></figure><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://cdn-images-1.medium.com/max/800/1*aBVP6jQKd0YntZjvur3pZQ.png" class="kg-image" alt="Ruby retry/scheduled tasks with Dead Letter Exchange in RabbitMQ" loading="lazy"><figcaption>Messages reside in retry.queue</figcaption></figure><p>Wait for 60 seconds and look at the terminal.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://cdn-images-1.medium.com/max/800/1*3m1L0bHfHqQVaFIDn8048Q.png" class="kg-image" alt="Ruby retry/scheduled tasks with Dead Letter Exchange in RabbitMQ" loading="lazy"><figcaption>Messages processed after 1 minute waiting in retry.queue</figcaption></figure><p>The messages are returned back to the <code>work.queue</code> , once again, only 1 message is processed as there are no slot for others, and they are pushed back to <code>retry.queue</code> by Rabbit.</p><p>If you grabbed the code from the repo, read the README and started Docker containers, then you can visit http://localhost:8080 and enjoy watching how messages are processed and requeued by yourself.</p><h4 id="notes-on-dlx-ttl">Notes on DLX &amp; TTL</h4><p>There are several ways how you can set a DLX and TTL.</p><p><strong>DLX:</strong></p><ol><li>When declaring a queue.</li><li>With RabbitMQ policies.</li></ol><p><strong>TTL</strong>:</p><ol><li>When declaring a queue</li><li>With RabbitMQ policies</li><li>On a per-message basis</li></ol><h4 id="pros-cons">Pros &amp; cons</h4><p>When you declare a queue, the only way to change options is to stop all the consumers and publishers, drop the queue and redefine it from the ground. It&#x2019;s not that good, as you don&#x2019;t know how can publish to it. But all configuration can be done via code.</p><p>When you create policies, you can change the policy at any time and no app redeployment will be needed. On the other hand, you must grant people permission to create policies, which is dangerous. Another option is to ask system administrators or operations team to change the policy, which can be a little bit annoying for them.</p><p>TTL can be added with an expiration header to message. When a message expires and gets to the head of the queue, it is automatically routed to DLX by RabbitMQ.</p><p>Feel free to ask questions in comments or connect directly on <a href="https://twitter.com/igkuz?ref=igkuz.ru" rel="noopener">twitter</a>.</p>]]></content:encoded></item><item><title><![CDATA[How to setup Ruby Object Mapper (ROM) for standalone project]]></title><description><![CDATA[How to setup Ruby Object Mapper with MySQL for standalone console project. Setup ROM Relations, Commands and tests.]]></description><link>https://igkuz.ru/how-to-setup-ruby-object-mapper-rom-for-standalone-project/</link><guid isPermaLink="false">5e9209026d9007355d8bde83</guid><category><![CDATA[Ruby]]></category><category><![CDATA[MySQL]]></category><category><![CDATA[Data Mapper]]></category><category><![CDATA[Ruby Object Mapper]]></category><dc:creator><![CDATA[Igor Kuznetsov]]></dc:creator><pubDate>Mon, 11 Mar 2019 07:00:00 GMT</pubDate><media:content url="https://igkuz.ru/content/images/2020/04/person-programming-ruby-res-3.png" medium="image"/><content:encoded><![CDATA[<img src="https://igkuz.ru/content/images/2020/04/person-programming-ruby-res-3.png" alt="How to setup Ruby Object Mapper (ROM) for standalone project"><p>I&#x2019;ve been looking at Data Mapper project for a long time. It transformed into Ruby Object Mapper and when I came up with a simple standalone project for collection post analytics, I decided to use it.</p><figure class="kg-card kg-image-card"><img src="https://cdn-images-1.medium.com/max/800/1*M5oYJ-sluW2Nh2SPBANeIA.png" class="kg-image" alt="How to setup Ruby Object Mapper (ROM) for standalone project" loading="lazy"></figure><p><a href="https://rom-rb.org/4.0/learn/?ref=igkuz.ru" rel="noopener">Official ROM documentation</a> is a great place to start, but there is a lack of information on some basic setup. That&#x2019;s why I thought that my experience will be useful for those who just came from Active Record and looking for first steps.</p><p>We&#x2019;re going to build a simple application that starts Pry as a console. There will be 2 entities&#x200A;&#x2014;&#x200A;Company and Post. You can check the <a href="https://github.com/igkuz/rom-sample-app?ref=igkuz.ru" rel="noopener"><strong>rom-sample-app</strong></a><strong> </strong>for the full code example on GitHub.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://cdn-images-1.medium.com/max/800/1*MeyTXJDgm69HG2UJcaAkXg.png" class="kg-image" alt="How to setup Ruby Object Mapper (ROM) for standalone project" loading="lazy"><figcaption>Company &amp; Post relations</figcaption></figure><h4 id="project-setup">Project setup</h4><pre><code class="language-bash">mkdir rom-sample-app &amp;&amp; cd rom-sample-app
touch Gemfile</code></pre><pre><code class="language-ruby">source &apos;https://rubygems.org&apos;

gem &apos;rom&apos;
gem &apos;rom-sql&apos;
gem &apos;rake&apos;
gem &apos;mysql2&apos;

gem &quot;awesome_print&quot;, require:&quot;ap&quot;
gem &apos;pry&apos;</code></pre><pre><code class="language-bash">bundle install</code></pre><p>Create <code>boot.rb</code> and require project dependencies.</p><figure class="kg-card kg-code-card"><pre><code class="language-ruby">ENV[&apos;RACK_ENV&apos;] ||= &apos;development&apos;
APP_ROOT = File.expand_path(&apos;../&apos;, __FILE__)
ENV[&apos;BUNDLE_GEMFILE&apos;] ||= File.join(APP_ROOT, &apos;/&apos;, &apos;Gemfile&apos;)
require &apos;bundler&apos;
Bundler.require(:default, ENV[&apos;RACK_ENV&apos;].to_sym)</code></pre><figcaption>In boot.rb we setup all dependencies from Gemfile.</figcaption></figure><p>Create <code>console</code>.</p><pre><code class="language-bash">touch console
chmod +x console</code></pre><pre><code class="language-ruby">#!/usr/bin/env ruby
require_relative &apos;boot&apos;

Pry.start</code></pre><p>Now we can get Pry console by calling <code>$ ./console</code> . Next we must connect to DB and create our entities.</p><h2 id="working-with-mysql-from-rom">Working with MySQL from ROM</h2><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://cdn-images-1.medium.com/max/800/1*MW1Ik8U21awUO-_sDhCsrw.png" class="kg-image" alt="How to setup Ruby Object Mapper (ROM) for standalone project" loading="lazy"><figcaption>Connecting ROM &amp;&#xA0;MySQL</figcaption></figure><p>Prepare <code>ROM::Configuration</code> to connect app to MySQL database.</p><p>ROM uses Sequel API and we have to count with it. Rails provide default Rake tasks for creating and deleting the DB, ROM doesn&#x2019;t. I won&#x2019;t describe the process of creating and deleting the database as it is necessary only 1 time in production environment. Most of the time this process involve DevOps engineers or system administrators and developers only grab the config. I suppose you can create the database for development and test environments on your own.</p><pre><code class="language-ruby">#!/usr/bin/env ruby
require_relative &apos;boot&apos;

db_config = {
  name: &apos;rom_app_development&apos;,
  host: &apos;db&apos;,
  user: &apos;root&apos;,
  password: &apos;&apos;,
  port: 3306,
  encoding: &apos;utf8mb4&apos;
}
configuration = ROM::Configuration.new(&quot;mysql2:///#{db_config[:name]}&quot;, db_config)
MAIN_CONTAINER = ROM.container(configuration)

Pry.start</code></pre><p>You shouldn&#x2019;t work with config like this in production environment. Read from separate file or env variables instead. But for the prototyping purposes it&#x2019;s more than enough.</p><p>Now we have MySQL server, created database and in console we can work with <code>MAIN_CONTAINER</code> object. Calling <code>ROM.container</code> will finalize the process of configuring ROM and all the hooks and callbacks will be invoked. So if you need something to register or configure please do it before calling <code>container</code> method.</p><h2 id="working-with-rom-migrations">Working with ROM migrations</h2><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://cdn-images-1.medium.com/max/800/0*1ARbzxsMdFExwA6M.jpg" class="kg-image" alt="How to setup Ruby Object Mapper (ROM) for standalone project" loading="lazy"><figcaption>ROM migrations</figcaption></figure><p>The SQL adapter uses Sequel migration API exposed by SQL gateways. You can either use the built-in rake tasks, or handle migrations manually. To load migration tasks simply require them and provide <code>db:setup</code> task which sets up ROM.</p><pre><code class="language-ruby">require_relative &apos;boot&apos;
require &apos;rom/sql/rake_task&apos;

namespace :db do
  task :setup do
    configuration = ROM::Configuration.new(:sql, &quot;mysql2:///#{CONFIG[&apos;db&apos;][&apos;name&apos;]}&quot;, CONFIG[&apos;db&apos;])
    ROM::SQL::RakeSupport.env = configuration
  end
end</code></pre><p>Create migrations for Company and Post.</p><pre><code class="language-bash">bundle exec rake db:create_migration[create_companies]
bundle exec rake db:create_migration[create_posts]</code></pre><p>Now there are 2 files in <code>db/migrate</code> directory. Migration names are prepended by timestamps. Timestamp migrations are created by default, but there is other setup where you can use just integers. <a href="https://rom-rb.org/4.0/learn/sql/migrations/?ref=igkuz.ru" rel="noopener nofollow">More on that in official docs.</a></p><p>I used ROM in real project, so I&#x2019;m going to put here the schema and explain why I needed these fields in other publication.</p><figure class="kg-card kg-code-card"><pre><code class="language-ruby">ROM::SQL.migration do
  change do
    create_table :companies do
      primary_key :id
      column :name, String, null: false
      column :domain, String, null: false
      column :state, String, null: false, default: &apos;running&apos;
      column :created_at, DateTime
      column :updated_at, DateTime
    end
  end
end</code></pre><figcaption><a href="https://gist.github.com/igkuz/5e2bc41b7b39ded786a8189069f3f351?ref=igkuz.ru#file-20190309132643_create_companies-rb">20190309132643_create_companies.rb</a></figcaption></figure><figure class="kg-card kg-code-card"><pre><code class="language-ruby">ROM::SQL.migration do
  change do
    create_table :posts do
      primary_key :id
      column :url, String, unique: true, null: false
      column :se_post, :boolean, null: false, default: false
      column :published_at, DateTime
      column :scrapped_at, DateTime, null: false
      column :error, String
      column :stats, JSON
      column :created_at, DateTime
      column :updated_at, DateTime
      foreign_key :company_id, :companies
    end
  end
end</code></pre><figcaption><a href="https://gist.github.com/igkuz/5e2bc41b7b39ded786a8189069f3f351?ref=igkuz.ru#file-20190309132708_create_posts-rb">20190309132708_create_posts.rb</a></figcaption></figure><p>Run migrations and check that schema exists. On <code>bundle exec rake db:migrate </code>there will be a check for pending migrations. We don&#x2019;t have any abstractions to work with data, just gateway connection for now.</p><pre><code class="language-bash">bundle exec rake db:migrate
  &lt;= db:migrate executed$ ./console
pry(main)&gt; MAIN_CONTAINER.
  gateways[:default].connection.schema(:companies)
=&gt; [[:id,
  {:primary_key=&gt;true,
   :auto_increment=&gt;true,
   :generated=&gt;false,
...
 [:updated_at, {:primary_key=&gt;false, :generated=&gt;false, :allow_null=&gt;true, :default=&gt;nil, :db_type=&gt;&quot;datetime&quot;, :type=&gt;:datetime, :ruby_default=&gt;nil}]]</code></pre><h2 id="rom-relations">ROM Relations</h2><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://igkuz.ru/content/images/2020/04/image-1.png" class="kg-image" alt="How to setup Ruby Object Mapper (ROM) for standalone project" loading="lazy"><figcaption>ROM Relations for Company and Post</figcaption></figure><p>Users of ROM implement <code>Relations</code>, which give access to data. A relation is defined as a set of tuples identified by unique pairs of attributes and their values. An example of relations is tables in a SQL server. Relations are really the heart of ROM. They provide APIs for reading the data from various databases, and low-level interfaces for making changes in the databases.</p><p>Let&#x2019;s create Post &amp; Company relations in <code>lib/relations/</code> directory.</p><figure class="kg-card kg-code-card"><pre><code class="language-ruby">class Companies &lt; ROM::Relation[:sql]
  schema(:companies, infer: true) do
    associations do
      has_many :posts
    end
  end
end</code></pre><figcaption><a href="https://gist.github.com/igkuz/a2803d02dfd78f71e54f79affe59ca1a?ref=igkuz.ru#file-companies-rb">companies.rb</a></figcaption></figure><figure class="kg-card kg-code-card"><pre><code class="language-ruby">class Posts &lt; ROM::Relation[:sql]
  schema(:posts, infer: true) do
    attribute :stats, Types::Coercible::JSON
    associations do
      belongs_to :company
    end
  end

  def by_url(url)
    where(url: url).to_a
  end
end</code></pre><figcaption><a href="https://gist.github.com/igkuz/a2803d02dfd78f71e54f79affe59ca1a?ref=igkuz.ru#file-posts-rb">posts.rb</a></figcaption></figure><p>As ROM uses dependency injection throughout the lib, we must register our components. <a href="https://rom-rb.org/4.0/learn/advanced/explicit-setup/?ref=igkuz.ru" rel="noopener nofollow">More on that in official docs</a>.</p><pre><code class="language-ruby">configuration.register_relation(Companies, Posts)</code></pre><p>We put this code into <code>console</code> file. When your app grows, you would definitely move it to a special place like initializer or smth similar. But for demonstration purposes it&#x2019;s more than enough to put it near the app running code.</p><p>Now we can access relations from MAIN_CONTAINER, like:</p><pre><code class="language-ruby">pry(main)&gt; MAIN_CONTAINER.relations[:companies].count
=&gt; 0
pry(main)&gt; MAIN_CONTAINER.relations[:posts].count
=&gt; 0</code></pre><p>Let&#x2019;s go further with ROM Commands. We want not only querying the data, but add or update some.</p><figure class="kg-card kg-image-card"><img src="https://cdn-images-1.medium.com/max/800/1*3BO6gL38HcwzJHilXS19XQ.png" class="kg-image" alt="How to setup Ruby Object Mapper (ROM) for standalone project" loading="lazy"></figure><p>Commands are used to make changes in your data. Every adapter provides its own command specializations, that can use database-specific features.</p><p>Core commands include following types:</p><ul><li><code>:create</code> - a command which inserts new tuples</li><li><code>:update</code> - a command which updates existing tuples</li><li><code>:delete</code> - a command which deletes existing tuples</li></ul><p>We are going to create commands for Posts and Companies and put them into <code>lib/commands/</code>.</p><figure class="kg-card kg-code-card"><pre><code class="language-ruby">class CreateCompany &lt; ROM::Commands::Create[:sql]
  relation :companies
  register_as :create
  result :one

  use :timestamps
  timestamp :created_at, :updated_at
end</code></pre><figcaption><a href="https://gist.github.com/igkuz/982c29a41aef4bf6e1bd4cafa986a622?ref=igkuz.ru#file-create_company-rb">create_company.rb</a></figcaption></figure><figure class="kg-card kg-code-card"><pre><code class="language-ruby">class CreatePost &lt; ROM::Commands::Create[:sql]
  relation :posts
  register_as :create
  result :one

  use :timestamps
  timestamp :scrapped_at, :created_at, :updated_at
end</code></pre><figcaption><a href="https://gist.github.com/igkuz/982c29a41aef4bf6e1bd4cafa986a622?ref=igkuz.ru#file-create_post-rb">create_post.rb</a></figcaption></figure><figure class="kg-card kg-code-card"><pre><code class="language-ruby">class DeleteCompany &lt; ROM::Commands::Delete[:sql]
  relation :companies
  register_as :delete
end</code></pre><figcaption><a href="https://gist.github.com/igkuz/982c29a41aef4bf6e1bd4cafa986a622?ref=igkuz.ru#file-delete_company-rb">delete_company.rb</a></figcaption></figure><figure class="kg-card kg-code-card"><pre><code class="language-ruby">class DeletePost &lt; ROM::Commands::Delete[:sql]
  relation :posts
  register_as :delete
end</code></pre><figcaption><a href="https://gist.github.com/igkuz/982c29a41aef4bf6e1bd4cafa986a622?ref=igkuz.ru#file-delete_post-rb">delete_post.rb</a></figcaption></figure><figure class="kg-card kg-code-card"><pre><code class="language-ruby">class UpdatePost &lt; ROM::Commands::Update[:sql]
  relation :posts
  register_as :update

  use :timestamps
  timestamp :updated_at
end	</code></pre><figcaption><a href="https://gist.github.com/igkuz/982c29a41aef4bf6e1bd4cafa986a622?ref=igkuz.ru#file-update_post-rb">update_post.rb</a></figcaption></figure><p>Note the lines</p><pre><code class="language-ruby">use timestamps
timestamp :created_at, :updated_at</code></pre><p>This how we use Timestamps plugin to automatically set the dates like Active Record does.</p><p>Now we must register our commands:</p><pre><code class="language-ruby">configuration.register_command(CreateCompany, DeleteCompany)
configuration.register_command(CreatePost, UpdatePost, DeletePost)</code></pre><p>Let&#x2019;s create the 1st company:</p><pre><code class="language-ruby">[1] pry(main)&gt; companies = MAIN_CONTAINER.relations[:companies]
[2] pry(main)&gt; companies.command(:create).call(
       name: &apos;My 1st Company&apos;, domain: &apos;http://example.com&apos;)
=&gt; {:id=&gt;1,
 :name=&gt;&quot;My 1st Company&quot;,
 :domain=&gt;&quot;http://example.com&quot;,
 :state=&gt;&quot;running&quot;,
 :created_at=&gt;2019-03-09 14:24:23 +0000,
 :updated_at=&gt;2019-03-09 14:24:23 +0000}</code></pre><p>That&#x2019;s it. <code>id</code> and <code>state</code> were assigned automatically, timestamps creation was also handled by ROM.</p><h2 id="testing-with-rom">Testing with ROM</h2><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://cdn-images-1.medium.com/max/800/0*VUsd3eXCQ9HhKa3Y.gif" class="kg-image" alt="How to setup Ruby Object Mapper (ROM) for standalone project" loading="lazy"><figcaption>&#xA9;<a href="https://www.toptal.com/qa/how-to-write-testable-code-and-why-it-matters?ref=igkuz.ru" data-href="https://www.toptal.com/qa/how-to-write-testable-code-and-why-it-matters" class="markup--anchor markup--figure-anchor" rel="nofollow noopener noopener" target="_blank">https://www.toptal.com/qa/how-to-write-testable-code-and-why-it-matters</a></figcaption></figure><p>The question then arises, &#x201C;How should I test this stuff?..&#x201D;. We&#x2019;re going to use RSpec with <a href="https://github.com/rom-rb/rom-factory?ref=igkuz.ru" rel="noopener nofollow">ROM factory</a>. It&#x2019;s kind of replacement for <a href="https://github.com/thoughtbot/factory_bot?ref=igkuz.ru" rel="noopener nofollow">factory_bot</a> gem by Thoughbot.</p><p>It&#x2019;s time to add <code>settings.yml</code> to project and put config there. Also we need to add <code>rspec</code> dependency to Gemfile and create test database. View the commits to the repo: <a href="https://github.com/igkuz/rom-sample-app/commit/1dfcc4d3cd609a36f0996718728f71d25449fd03?ref=igkuz.ru" rel="noopener nofollow">1</a>, <a href="https://github.com/igkuz/rom-sample-app/commit/b4dabfa4130d91466018b76f7b323246fead91ee?ref=igkuz.ru" rel="noopener nofollow">2</a>.</p><p>Define factories</p><figure class="kg-card kg-code-card"><pre><code class="language-ruby">let(:factories) do
  ROM::Factory.configure do |config|
    config.rom = MAIN_CONTAINER
  end
end

before do
  factories.define(:post) do |f|
    f.url { fake(:internet, :url, &apos;example.com&apos;) }
    f.se_post false
    f.stats {}
    f.association(:company)
  end
  factories.define(:company) do |f|
    f.sequence(:name) {|n| &quot;Company Name #{n}&quot;}
    f.domain { &quot;https://#{fake(:internet, :domain_name)}&quot; }
    f.state &quot;running&quot;
  end
  factories.define(with_post: :company) do |f|
    f.association(:posts, count: 1)
  end
end</code></pre><figcaption><a href="https://gist.github.com/igkuz/1ffec2719147713658eeb8044c258b5b?ref=igkuz.ru#file-factories-rb">factories.rb</a></figcaption></figure><p>Check <code>company_spec.rb</code> in <a href="https://github.com/igkuz/rom-sample-app?ref=igkuz.ru" rel="noopener nofollow">repository</a> for simple test of creating company with 1 post.</p><p>This is it. We created a standalone console application with Ruby Object Mapper. Additional info on running app in docker container is in README.</p><p>If you have any questions, write a comment or connect directly on <a href="https://twitter.com/igkuz?ref=igkuz.ru" rel="noopener nofollow">twitter</a>.</p>]]></content:encoded></item><item><title><![CDATA[Socket Activated Containers (Unicorn + Systemd)]]></title><description><![CDATA[Как с помощью systemd и socket activation сделать старт/стоп Docker контейнеров]]></description><link>https://igkuz.ru/socket-activated-containers-unicorn-systemd/</link><guid isPermaLink="false">5e9209026d9007355d8bde85</guid><category><![CDATA[Containers]]></category><category><![CDATA[Docker]]></category><category><![CDATA[Ruby]]></category><category><![CDATA[Systemd]]></category><category><![CDATA[devops]]></category><dc:creator><![CDATA[Igor Kuznetsov]]></dc:creator><pubDate>Tue, 17 Jul 2018 07:00:00 GMT</pubDate><media:content url="https://igkuz.ru/content/images/2020/04/socket-activated-containers.jpeg" medium="image"/><content:encoded><![CDATA[<img src="https://igkuz.ru/content/images/2020/04/socket-activated-containers.jpeg" alt="Socket Activated Containers (Unicorn + Systemd)"><p>&#x423; &#x43A;&#x43B;&#x438;&#x435;&#x43D;&#x442;&#x430; &#x435;&#x441;&#x442;&#x44C; &#x431;&#x43E;&#x43B;&#x44C;&#x448;&#x43E;&#x435; &#x43A;&#x43E;&#x43B;&#x438;&#x447;&#x435;&#x441;&#x442;&#x432;&#x43E; &#x43C;&#x435;&#x434;&#x438;&#x439;&#x43D;&#x44B;&#x445; &#x441;&#x43F;&#x435;&#x446; &#x43F;&#x440;&#x43E;&#x435;&#x43A;&#x442;&#x43E;&#x432; (~250). &#x42D;&#x442;&#x43E; &#x432;&#x438;&#x434;&#x436;&#x435;&#x442;&#x44B;, &#x43B;&#x435;&#x43D;&#x434;&#x438;&#x43D;&#x433;&#x438;, &#x430;&#x43F;&#x438;&#x448;&#x43A;&#x438; &#x438; &#x442;.&#x434;. &#x421; 2012 &#x433;&#x43E;&#x434;&#x430; &#x44D;&#x442;&#x43E; &#x432;&#x441;&#x435; &#x436;&#x438;&#x432;&#x435;&#x442; &#x43D;&#x430; 1 &#x43C;&#x430;&#x448;&#x438;&#x43D;&#x435; &#x441;&#x43E; &#x441;&#x432;&#x44F;&#x437;&#x43A;&#x43E;&#x439; Nginx + Passenger + Ruby.</p><p>&#x412;&#x441;&#x435; &#x445;&#x43E;&#x440;&#x43E;&#x448;&#x43E;, &#x437;&#x430; &#x438;&#x441;&#x43A;&#x43B;&#x44E;&#x447;&#x435;&#x43D;&#x438;&#x435;&#x43C; &#x43C;&#x43E;&#x43C;&#x435;&#x43D;&#x442;&#x430; &#x43E;&#x431;&#x43D;&#x43E;&#x432;&#x43B;&#x435;&#x43D;&#x438;&#x44F; &#x41E;&#x421;, &#x43A;&#x43E;&#x433;&#x434;&#x430; &#x432;&#x441;&#x435; &#x43F;&#x440;&#x43E;&#x431;&#x43B;&#x435;&#x43C;&#x44B; &#x441;&#x43E; &#x441;&#x442;&#x430;&#x440;&#x44B;&#x43C;&#x438;/&#x43D;&#x43E;&#x432;&#x44B;&#x43C;&#x438; &#x432;&#x435;&#x440;&#x441;&#x438;&#x44F;&#x43C;&#x438; &#x43F;&#x430;&#x43A;&#x435;&#x442;&#x43E;&#x432; &#x432;&#x44B;&#x43B;&#x435;&#x437;&#x430;&#x44E;&#x442; &#x438; &#x437;&#x430;&#x44F;&#x432;&#x43B;&#x44F;&#x44E;&#x442; &#x43E; &#x441;&#x435;&#x431;&#x435; &#x432; &#x43F;&#x43E;&#x43B;&#x43D;&#x44B;&#x439; &#x433;&#x43E;&#x43B;&#x43E;&#x441;.</p><p>&#x41A;&#x430;&#x437;&#x430;&#x43B;&#x43E;&#x441;&#x44C; &#x431;&#x44B;, &#x438;&#x434;&#x435;&#x430;&#x43B;&#x44C;&#x43D;&#x430;&#x44F; &#x438;&#x441;&#x442;&#x43E;&#x440;&#x438;&#x44F; &#x434;&#x43B;&#x44F; &#x43A;&#x43E;&#x43D;&#x442;&#x435;&#x439;&#x43D;&#x435;&#x440;&#x43E;&#x432;, &#x43D;&#x43E; &#x435;&#x441;&#x442;&#x44C; &#x43E;&#x434;&#x43D;&#x43E; &#x43D;&#x43E;. Passenger &#x438;&#x43B;&#x438; PHP-FPM &#x443;&#x43C;&#x435;&#x44E;&#x442; &#x442;&#x43E;, &#x447;&#x442;&#x43E; &#x438;&#x437; &#x43A;&#x43E;&#x440;&#x43E;&#x431;&#x43A;&#x438; <a href="https://github.com/kubernetes/kubernetes/issues/484?ref=igkuz.ru" rel="noopener nofollow">&#x43D;&#x435;&#x442; &#x434;&#x430;&#x436;&#x435; &#x443; Kubernetes</a> &#x2014; &#x44D;&#x442;&#x43E; &#x441;&#x442;&#x430;&#x440;&#x442; &#x43F;&#x43E; &#x432;&#x445;&#x43E;&#x434;&#x44F;&#x449;&#x435;&#x43C;&#x443; &#x442;&#x440;&#x430;&#x444;&#x438;&#x43A;&#x443;.</p><p>&#x41D;&#x430; &#x43F;&#x440;&#x43E;&#x441;&#x442;&#x43E;&#x440;&#x430;&#x445; &#x441;&#x435;&#x442;&#x438; &#x44D;&#x442;&#x43E; &#x43D;&#x430;&#x437;&#x44B;&#x432;&#x430;&#x435;&#x442;&#x441;&#x44F; (&#x433;&#x443;&#x433;&#x43B;&#x438;&#x442;&#x441;&#x44F;) &#x2014; Socket Activation. &#x41D;&#x430; Network &#x438;&#x43B;&#x438; Unix &#x441;&#x43E;&#x43A;&#x435;&#x442; &#x43F;&#x440;&#x438;&#x445;&#x43E;&#x434;&#x438;&#x442; &#x43F;&#x430;&#x43A;&#x435;&#x442;, &#x441;&#x435;&#x440;&#x432;&#x438;&#x441; &#x437;&#x430;&#x43F;&#x443;&#x441;&#x43A;&#x430;&#x435;&#x442;&#x441;&#x44F;. &#x41F;&#x43E;&#x43A;&#x43E;&#x43F;&#x430;&#x432;&#x448;&#x438;&#x441;&#x44C; &#x43D;&#x430; Stack Overflow &#x438; &#x43D;&#x435;&#x43A;&#x43E;&#x442;&#x43E;&#x440;&#x44B;&#x445; &#x430;&#x434;&#x43C;&#x438;&#x43D;&#x441;&#x43A;&#x438;&#x445; &#x444;&#x43E;&#x440;&#x443;&#x43C;&#x430;&#x445;, &#x43F;&#x43E;&#x43D;&#x44F;&#x43B;, &#x447;&#x442;&#x43E; &#x43C;&#x44B;&#x441;&#x43B;&#x44C; &#x43E; &#x442;&#x43E;&#x43C;, &#x447;&#x442;&#x43E; &#x43A;&#x43E;&#x43D;&#x442;&#x435;&#x439;&#x43D;&#x435;&#x440;, &#x43C;&#x43E;&#x436;&#x43D;&#x43E; &#x442;&#x43E;&#x43B;&#x44C;&#x43A;&#x43E; &#x43F;&#x43E; &#x43D;&#x435;&#x43E;&#x431;&#x445;&#x43E;&#x434;&#x438;&#x43C;&#x43E;&#x441;&#x442;&#x438; &#x43F;&#x43E;&#x434;&#x43D;&#x438;&#x43C;&#x430;&#x442;&#x44C; &#x438;&#x43D;&#x442;&#x435;&#x440;&#x435;&#x441;&#x443;&#x435;&#x442; &#x43C;&#x43D;&#x43E;&#x433;&#x438;&#x445;. &#x422;&#x430;&#x43A;&#x438;&#x435; &#x437;&#x430;&#x43F;&#x440;&#x43E;&#x441;&#x44B; &#x435;&#x441;&#x442;&#x44C; &#x443; &#x431;&#x43E;&#x43B;&#x44C;&#x448;&#x438;&#x445; &#x440;&#x435;&#x431;&#x44F;&#x442; &#x2014; &#x43F;&#x440;&#x438;&#x432;&#x435;&#x442; &#x432;&#x435;&#x43B;&#x43E;&#x441;&#x438;&#x43F;&#x435;&#x434;&#x44B; (&#x447;&#x438;&#x442;&#x430;&#x439; &#x441;&#x432;&#x43E;&#x438; &#x440;&#x435;&#x448;&#x435;&#x43D;&#x438;&#x44F;).</p><p>&#x41E;&#x43A;&#x430;&#x437;&#x44B;&#x432;&#x430;&#x435;&#x442;&#x441;&#x44F; &#x442;&#x43E;, &#x447;&#x442;&#x43E; &#x43D;&#x443;&#x436;&#x43D;&#x43E; &#x43D;&#x430;&#x43F;&#x438;&#x441;&#x430;&#x43B;&#x438; &#x443;&#x436;&#x435; &#x43B;&#x435;&#x442; 7 &#x43D;&#x430;&#x437;&#x430;&#x434;. <a href="http://0pointer.de/blog/projects/socket-activation.html?ref=igkuz.ru" rel="noopener nofollow">&#x41F;&#x43E;&#x441;&#x442;</a> &#x43F;&#x440;&#x43E; &#x440;&#x435;&#x430;&#x43B;&#x438;&#x437;&#x430;&#x446;&#x438;&#x44E; &#x444;&#x443;&#x43D;&#x43A;&#x446;&#x438;&#x43E;&#x43D;&#x430;&#x43B;&#x430; &#x432; systemd &#x434;&#x430;&#x442;&#x438;&#x440;&#x43E;&#x432;&#x430;&#x43D; 2011 &#x433;&#x43E;&#x434;&#x43E;&#x43C;. &#x41D;&#x443; &#x438; &#x432; 2013 &#x443;&#x436;&#x435; &#x432;&#x44B;&#x448;&#x435;&#x43B; <a href="http://0pointer.de/blog/projects/socket-activated-containers.html?ref=igkuz.ru" rel="noopener nofollow">&#x43F;&#x43E;&#x441;&#x442;</a> &#x43F;&#x440;&#x43E; &#x441;&#x442;&#x430;&#x440;&#x442; &#x43A;&#x43E;&#x43D;&#x442;&#x435;&#x439;&#x43D;&#x435;&#x440;&#x430; &#x441; &#x43F;&#x43E;&#x43C;&#x43E;&#x449;&#x44C;&#x44E; &#x442;&#x43E;&#x439; &#x436;&#x435; &#x444;&#x443;&#x43D;&#x43A;&#x446;&#x438;&#x43E;&#x43D;&#x430;&#x43B;&#x44C;&#x43D;&#x43E;&#x441;&#x442;&#x438;. &#x415;&#x441;&#x442;&#x44C; &#x43E;&#x434;&#x43D;&#x43E; &#x43D;&#x43E;, &#x442;&#x430;&#x43C; &#x438;&#x441;&#x43F;&#x43E;&#x43B;&#x44C;&#x437;&#x443;&#x44E;&#x442;&#x441;&#x44F; &#x441;&#x442;&#x430;&#x43D;&#x434;&#x430;&#x440;&#x442;&#x43D;&#x44B;&#x435; &#x441;&#x440;&#x435;&#x434;&#x441;&#x442;&#x432;&#x430; systemd &#x434;&#x43B;&#x44F; &#x432;&#x438;&#x440;&#x442;&#x443;&#x430;&#x43B;&#x438;&#x437;&#x430;&#x446;&#x438;&#x438;, &#x43D;&#x430;&#x441; &#x436;&#x435; &#x438;&#x43D;&#x442;&#x435;&#x440;&#x435;&#x441;&#x443;&#x44E;&#x442; &#x431;&#x43E;&#x43B;&#x435;&#x435; &#x43F;&#x43E;&#x43F;&#x443;&#x43B;&#x44F;&#x440;&#x43D;&#x44B;&#x435; &#x43D;&#x430; &#x434;&#x430;&#x43D;&#x43D;&#x44B;&#x439; &#x43C;&#x43E;&#x43C;&#x435;&#x43D;&#x442; Docker.</p><figure class="kg-card kg-image-card kg-card-hascaption"><img src="https://cdn-images-1.medium.com/max/800/1*PITVMrEg3tFTHU50hKStcQ.gif" class="kg-image" alt="Socket Activated Containers (Unicorn + Systemd)" loading="lazy"><figcaption>&#x421;&#x445;&#x435;&#x43C;&#x443; &#x437;&#x430;&#x431;&#x440;&#x430;&#x43B; &#x438;&#x437; <a href="https://developer.atlassian.com/blog/2015/03/docker-systemd-socket-activation/?ref=igkuz.ru" data-href="https://developer.atlassian.com/blog/2015/03/docker-systemd-socket-activation/" class="markup--anchor markup--figure-anchor" rel="noopener" target="_blank">&#x431;&#x43B;&#x43E;&#x433;&#x430; Atlassian</a>.</figcaption></figure><p>&#x412;&#x43E; &#x432;&#x441;&#x435;&#x445; &#x441;&#x442;&#x430;&#x442;&#x44C;&#x44F;&#x445; &#x433;&#x43E;&#x432;&#x43E;&#x440;&#x438;&#x43B;&#x438; &#x43E; proxy &#x441;&#x435;&#x440;&#x432;&#x438;&#x441;&#x435;, &#x43A;&#x43E;&#x442;&#x43E;&#x440;&#x44B;&#x439; &#x43F;&#x440;&#x438;&#x43D;&#x438;&#x43C;&#x430;&#x435;&#x442; &#x442;&#x440;&#x430;&#x444;&#x438;&#x43A; &#x438; &#x43E;&#x442;&#x432;&#x435;&#x447;&#x430;&#x435;&#x442; &#x437;&#x430; &#x437;&#x430;&#x43F;&#x443;&#x441;&#x43A; &#x43A;&#x43E;&#x43D;&#x442;&#x435;&#x439;&#x43D;&#x435;&#x440;&#x430;. G&#x43E;&#x447;&#x435;&#x43C;&#x443; &#x43D;&#x435;&#x43B;&#x44C;&#x437;&#x44F; &#x441;&#x43E;&#x43A;&#x435;&#x442; &#x438;&#x441;&#x43F;&#x43E;&#x43B;&#x44C;&#x437;&#x43E;&#x432;&#x430;&#x442;&#x44C; &#x441;&#x440;&#x430;&#x437;&#x443; &#x432; &#x43A;&#x43E;&#x43D;&#x442;&#x435;&#x439;&#x43D;&#x435;&#x440;&#x435;? &#x412;&#x43E;&#x43F;&#x440;&#x43E;&#x441; &#x44D;&#x442;&#x43E;&#x442; &#x432;&#x43E;&#x437;&#x43D;&#x438;&#x43A;&#x430;&#x435;&#x442;, &#x43F;&#x43E;&#x442;&#x43E;&#x43C;&#x443; &#x447;&#x442;&#x43E; &#x43D;&#x430; &#x43A;&#x430;&#x436;&#x434;&#x44B;&#x439; &#x441;&#x435;&#x440;&#x432;&#x438;&#x441; &#x43F;&#x440;&#x438;&#x434;&#x435;&#x442;&#x441;&#x44F; &#x434;&#x435;&#x43B;&#x430;&#x442;&#x44C; 3 &#x43A;&#x43E;&#x43D;&#x444;&#x438;&#x433;&#x430; systemd &#x438; &#x43C;&#x438;&#x43D;&#x438;&#x43C;&#x443;&#x43C; 2 &#x441;&#x43E;&#x43A;&#x435;&#x442;&#x430;, &#x447;&#x442;&#x43E; &#x43A;&#x430;&#x43A; &#x43C;&#x43D;&#x435; &#x43A;&#x430;&#x437;&#x430;&#x43B;&#x43E;&#x441;&#x44C; &#x43C;&#x43D;&#x43E;&#x433;&#x43E; &#x438; &#x43D;&#x435; &#x441;&#x43B;&#x438;&#x448;&#x43A;&#x43E;&#x43C; &#x43A;&#x440;&#x430;&#x441;&#x438;&#x432;&#x43E;. &#x41F;&#x43E;&#x441;&#x43C;&#x43E;&#x442;&#x440;&#x435;&#x43B; &#x43F;&#x43E;&#x442;&#x43E;&#x43C; &#x43D;&#x430; &#x43A;&#x43E;&#x43D;&#x444;&#x438;&#x433;&#x438; kubernetes &#x438; 3 &#x43A;&#x43E;&#x43D;&#x444;&#x438;&#x433;&#x430; systemd &#x43F;&#x43E;&#x43A;&#x430;&#x437;&#x430;&#x43B;&#x438;&#x441;&#x44C; &#x43C;&#x430;&#x43B;&#x435;&#x43D;&#x44C;&#x43A;&#x438;&#x43C;&#x438;, &#x43F;&#x440;&#x43E;&#x441;&#x442;&#x44B;&#x43C;&#x438; &#x438; &#x43F;&#x43E;&#x43D;&#x44F;&#x442;&#x43D;&#x44B;&#x43C;&#x438;.</p><p>&#x41D;&#x43E; &#x442;&#x430;&#x43A; &#x447;&#x442;&#x43E; &#x441; &#x441;&#x43E;&#x43A;&#x435;&#x442;&#x43E;&#x43C; &#x442;&#x43E;? &#x410; &#x432;&#x43E;&#x442; &#x44F; &#x43D;&#x435; &#x43D;&#x430;&#x448;&#x435;&#x43B; &#x441;&#x43F;&#x43E;&#x441;&#x43E;&#x431;&#x430; &#x43A;&#x430;&#x43A; &#x435;&#x433;&#x43E; &#x43F;&#x440;&#x43E;&#x431;&#x440;&#x43E;&#x441;&#x438;&#x442;&#x44C; &#x432; &#x43A;&#x43E;&#x43D;&#x442;&#x435;&#x439;&#x43D;&#x435;&#x440;. &#x415;&#x441;&#x43B;&#x438; &#x43A;&#x442;&#x43E; &#x437;&#x43D;&#x430;&#x435;&#x442;, &#x441; &#x440;&#x430;&#x434;&#x43E;&#x441;&#x442;&#x44C;&#x44E; &#x43F;&#x43E;&#x441;&#x43B;&#x443;&#x448;&#x430;&#x44E;. &#x41F;&#x440;&#x43E;&#x431;&#x43B;&#x435;&#x43C;&#x430; &#x43D;&#x435; &#x432; &#x441;&#x43E;&#x444;&#x442;&#x435; (unicorn &#x438; puma), &#x43A;&#x43E;&#x442;&#x43E;&#x440;&#x44B;&#x439; &#x43C;&#x43E;&#x436;&#x435;&#x442; &#x43F;&#x435;&#x440;&#x435;&#x438;&#x441;&#x43F;&#x43E;&#x43B;&#x44C;&#x437;&#x43E;&#x432;&#x430;&#x442;&#x44C; &#x43F;&#x440;&#x43E;&#x431;&#x440;&#x43E;&#x448;&#x435;&#x43D;&#x43D;&#x44B;&#x439; &#x441;&#x43E;&#x43A;&#x435;&#x442;. &#x415;&#x441;&#x442;&#x44C; &#x441;&#x442;&#x430;&#x43D;&#x434;&#x430;&#x440;&#x442;&#x43D;&#x44B;&#x435; &#x43F;&#x440;&#x43E;&#x446;&#x435;&#x434;&#x443;&#x440;&#x44B; &#x434;&#x43B;&#x44F; &#x44D;&#x442;&#x43E;&#x433;&#x43E;. &#x427;&#x435;&#x440;&#x435;&#x437; ENV &#x43F;&#x435;&#x440;&#x435;&#x43C;&#x435;&#x43D;&#x43D;&#x44B;&#x435; &#x43F;&#x435;&#x440;&#x435;&#x434;&#x430;&#x44E;&#x442;&#x441;&#x44F; ID &#x43F;&#x440;&#x43E;&#x446;&#x435;&#x441;&#x441;&#x430; (<em>LISTEN_PID) </em>&#x438; &#x43D;&#x43E;&#x43C;&#x435;&#x440; &#x441;&#x43B;&#x443;&#x448;&#x430;&#x44E;&#x449;&#x435;&#x433;&#x43E; &#x441;&#x43E;&#x43A;&#x435;&#x442;&#x430; (<em>LISTEN_FDS</em>), &#x43F;&#x43E;&#x441;&#x43B;&#x435; &#x447;&#x435;&#x433;&#x43E; &#x441;&#x43E;&#x444;&#x442; &#x43D;&#x435; &#x434;&#x43E;&#x43B;&#x436;&#x435;&#x43D; &#x43F;&#x44B;&#x442;&#x430;&#x442;&#x44C;&#x441;&#x44F; &#x43E;&#x442;&#x43A;&#x440;&#x44B;&#x442;&#x44C; &#x43D;&#x43E;&#x432;&#x44B;&#x439;, &#x430; &#x43F;&#x435;&#x440;&#x435;&#x438;&#x441;&#x43F;&#x43E;&#x43B;&#x44C;&#x437;&#x43E;&#x432;&#x430;&#x442;&#x44C; (&#x43F;&#x43E;&#x434;&#x43A;&#x43B;&#x44E;&#x447;&#x438;&#x442;&#x44C;&#x441;&#x44F;) &#x43A; &#x441;&#x43E;&#x43A;&#x435;&#x442;&#x443; &#x441; &#x441;&#x43E;&#x43E;&#x442;&#x432;&#x435;&#x442;&#x441;&#x442;&#x432;&#x443;&#x44E;&#x449;&#x438;&#x43C;&#x438; &#x43A;&#x43E;&#x43E;&#x440;&#x434;&#x438;&#x43D;&#x430;&#x442;&#x430;&#x43C;&#x438;.</p><p>&#x41F;&#x440;&#x43E;&#x431;&#x43B;&#x435;&#x43C;&#x430; &#x437;&#x430;&#x43A;&#x43B;&#x44E;&#x447;&#x430;&#x435;&#x442;&#x441;&#x44F; &#x432; &#x442;&#x43E;&#x43C;, &#x447;&#x442;&#x43E; ID &#x43F;&#x440;&#x43E;&#x446;&#x435;&#x441;&#x441;&#x430; &#x438; &#x441;&#x441;&#x44B;&#x43B;&#x43A;&#x443; &#x43D;&#x430; &#x441;&#x43E;&#x43A;&#x435;&#x442; &#x431;&#x443;&#x434;&#x443;&#x442; &#x43F;&#x435;&#x440;&#x435;&#x434;&#x430;&#x43D;&#x44B; &#x441; host &#x43C;&#x430;&#x448;&#x438;&#x43D;&#x44B;, &#x43A;&#x43E;&#x43D;&#x442;&#x435;&#x439;&#x43D;&#x435;&#x440; &#x435;&#x441;&#x442;&#x435;&#x441;&#x442;&#x432;&#x435;&#x43D;&#x43D;&#x43E; &#x43D;&#x438;&#x447;&#x435;&#x433;&#x43E; &#x43E; &#x43D;&#x438;&#x445; &#x43D;&#x435; &#x437;&#x43D;&#x430;&#x435;&#x442;.</p><p>&#x428;&#x430;&#x440;&#x438;&#x442;&#x44C; &#x434;&#x430;&#x43D;&#x43D;&#x44B;&#x435; &#x441; &#x445;&#x43E;&#x441;&#x442; &#x43C;&#x430;&#x448;&#x438;&#x43D;&#x43E;&#x439; &#x43A;&#x43E;&#x43D;&#x435;&#x447;&#x43D;&#x43E; &#x43C;&#x43E;&#x436;&#x43D;&#x43E;, &#x43D;&#x43E; &#x431;&#x435;&#x437;&#x43E;&#x43F;&#x430;&#x441;&#x43D;&#x43E; &#x43B;&#x438;?</p><figure class="kg-card kg-code-card"><pre><code class="language-ruby">require &apos;bundler/setup&apos;
Bundler.require

require &apos;rack&apos;

app = Proc.new do |env|
  [&apos;200&apos;, {&apos;Content-Type&apos; =&gt; &apos;text/html&apos;}, [&apos;Simple app for test&apos;]]
end

run app</code></pre><figcaption><a href="https://gist.github.com/igkuz/87d2087ccf333870c50cbc04ebfedf04?ref=igkuz.ru#file-config-ru">config.ru</a></figcaption></figure><figure class="kg-card kg-code-card"><pre><code class="language-Docker">FROM ruby:2.4
RUN mkdir /app
COPY Gemfile Gemfile.lock /app/
WORKDIR /app
RUN bundle install
ADD config.ru /app/
ADD unicorn.rb /app/
CMD [&quot;bundle&quot;, &quot;exec&quot;, &quot;--keep-file-descriptors&quot;, &quot;unicorn&quot;, &quot;-c&quot;, &quot;unicorn.rb&quot;]</code></pre><figcaption><a href="https://gist.github.com/igkuz/87d2087ccf333870c50cbc04ebfedf04?ref=igkuz.ru#file-dockerfile">Dockerfile</a></figcaption></figure><figure class="kg-card kg-code-card"><pre><code class="language-ruby">source &apos;https://rubygems.org&apos;

gem &apos;unicorn&apos;
gem &apos;rack&apos;</code></pre><figcaption><a href="https://gist.github.com/igkuz/87d2087ccf333870c50cbc04ebfedf04?ref=igkuz.ru#file-gemfile">Gemfile</a></figcaption></figure><figure class="kg-card kg-code-card"><pre><code class="language-ruby">GEM
  remote: https://rubygems.org/
  specs:
    kgio (2.11.2)
    rack (2.0.5)
    raindrops (0.19.0)
    unicorn (5.4.0)
      kgio (~&gt; 2.6)
      raindrops (~&gt; 0.7)

PLATFORMS
  ruby

DEPENDENCIES
  rack
  unicorn

BUNDLED WITH
   1.16.1</code></pre><figcaption><a href="https://gist.github.com/igkuz/87d2087ccf333870c50cbc04ebfedf04?ref=igkuz.ru#file-gemfile-lock">Gemfile.lock</a></figcaption></figure><figure class="kg-card kg-code-card"><pre><code class="language-bash">[Unit]
Description=Socket Activation with Unicorn Service
After=network.target sact-test.socket
Requires=sact-test.socket

[Service]
ExecStart=/usr/bin/docker run --user 1001 --rm --name sact-test-n -v &apos;/apps/sact/sact-git/tmp:/app/tmp&apos; -e &apos;SOCKET_FILE=/app/tmp/sockets/unicorn.sock&apos; sact-test
ExecStartPost=/bin/sleep 1
SyslogIdentifier=sact-test-docker
ExecStop=/usr/bin/docker stop sact-test-n</code></pre><figcaption><a href="https://gist.github.com/igkuz/87d2087ccf333870c50cbc04ebfedf04?ref=igkuz.ru#file-sact-test-docker-service">sact-test-docker.service</a></figcaption></figure><figure class="kg-card kg-code-card"><pre><code class="language-bash">[Unit]
Requires=sact-test-docker.service
After=sact-test-docker.service

[Service]
SyslogIdentifier=sact-test-docker
ExecStart=/lib/systemd/systemd-socket-proxyd /apps/sact/sact-git/tmp/sockets/unicorn.sock</code></pre><figcaption><a href="https://gist.github.com/igkuz/87d2087ccf333870c50cbc04ebfedf04?ref=igkuz.ru#file-sact-test-service">sact-test.service</a></figcaption></figure><figure class="kg-card kg-code-card"><pre><code class="language-bash">[Unit]
Description=Socket Activation with Unicorn
PartOf=sact-test.service

[Socket]
SocketUser=sact
SocketGroup=sact
SocketMode=0777
Backlog=2048
ListenStream=/apps/sact/sact-git/tmp/sockets/unicorn-proxy.sock

[Install]
WantedBy=sockets.target</code></pre><figcaption><a href="https://gist.github.com/igkuz/87d2087ccf333870c50cbc04ebfedf04?ref=igkuz.ru#file-sact-test-socket">sact-test.socket</a></figcaption></figure><figure class="kg-card kg-code-card"><pre><code class="language-config">upstream app_sact {
    server unix:/apps/sact/sact-git/tmp/sockets/unicorn-proxy.sock;
}

server {
  listen 80;
  charset utf-8;
  set $application_name &quot;sact&quot;;

  location / {
    try_files $uri $uri.html @application;
  }

    location @application {
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_hide_header X-User-Id;

        proxy_redirect off;
        proxy_pass http://app_$application_name;
        break;
    }
}</code></pre><figcaption><a href="https://gist.github.com/igkuz/87d2087ccf333870c50cbc04ebfedf04?ref=igkuz.ru#file-sact-conf">sact.conf</a></figcaption></figure><figure class="kg-card kg-code-card"><pre><code class="language-ruby">worker_processes 2
timeout 30
listen ENV[&apos;SOCKET_FILE&apos;] || 8080, backlog: 2048
working_directory ENV[&apos;APP_PATH&apos;] || &apos;/app/</code></pre><figcaption><a href="https://gist.github.com/igkuz/87d2087ccf333870c50cbc04ebfedf04?ref=igkuz.ru#file-unicorn-rb">unicorn.rb</a></figcaption></figure><p>&#x421;&#x434;&#x435;&#x43B;&#x430;&#x43B; <a href="https://gist.github.com/igkuz/87d2087ccf333870c50cbc04ebfedf04?ref=igkuz.ru" rel="noopener nofollow">gist</a> &#x441; &#x444;&#x430;&#x439;&#x43B;&#x430;&#x43C;&#x438; &#x434;&#x43B;&#x44F; &#x442;&#x435;&#x441;&#x442;&#x43E;&#x432;. &#x41F;&#x440;&#x43E;&#x441;&#x442;&#x435;&#x439;&#x448;&#x435;&#x435; Rack &#x43F;&#x440;&#x438;&#x43B;&#x43E;&#x436;&#x435;&#x43D;&#x438;&#x435; &#x438; &#x43D;&#x430;&#x431;&#x43E;&#x440; &#x441;&#x435;&#x440;&#x432;&#x438;&#x441;&#x43E;&#x432; &#x434;&#x43B;&#x44F; systemd. &#x427;&#x442;&#x43E;&#x431;&#x44B; &#x44D;&#x442;&#x43E; &#x432;&#x441;&#x435; &#x437;&#x430;&#x432;&#x435;&#x43B;&#x43E;&#x441;&#x44C; &#x43D;&#x430;&#x434;&#x43E; &#x437;&#x430;&#x432;&#x435;&#x441;&#x442;&#x438; &#x43E;&#x442;&#x434;&#x435;&#x43B;&#x44C;&#x43D;&#x43E;&#x433;&#x43E; &#x43F;&#x43E;&#x43B;&#x44C;&#x437;&#x43E;&#x432;&#x430;&#x442;&#x435;&#x43B;&#x44F;, &#x43D;&#x430;&#x437;&#x432;&#x430;&#x43B; &#x435;&#x433;&#x43E; <code>sact</code>, &#x438; &#x441;&#x43B;&#x43E;&#x436;&#x438;&#x442;&#x44C; <code>Gemfile, Gemfile.lock, unicorn.rb, config.ru </code>&#x444;&#x430;&#x439;&#x43B;&#x44B; &#x432; <code>/apps/sact/sact-git</code> . &#x423;&#x441;&#x442;&#x430;&#x43D;&#x43E;&#x432;&#x438;&#x442;&#x44C; docker, &#x441;&#x43B;&#x43E;&#x436;&#x438;&#x442;&#x44C; systemd &#x441;&#x435;&#x440;&#x432;&#x438;&#x441;&#x43D;&#x44B;&#x439; &#x444;&#x430;&#x439;&#x43B;&#x44B; &#x432; <code>/etc/systemd/system</code> &#x438; &#x43F;&#x435;&#x440;&#x435;&#x437;&#x430;&#x433;&#x440;&#x443;&#x437;&#x438;&#x442;&#x44C; &#x434;&#x435;&#x43C;&#x43E;&#x43D;&#x430; &#x447;&#x435;&#x440;&#x435;&#x437; <code>systemctl daemon-reload</code> . &#x422;&#x430;&#x43A;&#x436;&#x435; &#x43F;&#x43E;&#x43D;&#x430;&#x434;&#x43E;&#x431;&#x438;&#x442;&#x44C;&#x441;&#x44F; nginx. &#x41D;&#x43E; &#x434;&#x443;&#x43C;&#x430;&#x44E; &#x434;&#x43B;&#x44F; &#x442;&#x435;&#x445; &#x43A;&#x442;&#x43E; &#x44D;&#x442;&#x43E; &#x447;&#x438;&#x442;&#x430;&#x435;&#x442; &#x43D;&#x435; &#x441;&#x43E;&#x441;&#x442;&#x430;&#x432;&#x438;&#x442; &#x431;&#x43E;&#x43B;&#x44C;&#x448;&#x43E;&#x433;&#x43E; &#x442;&#x440;&#x443;&#x434;&#x430; &#x440;&#x430;&#x437;&#x43E;&#x431;&#x440;&#x430;&#x442;&#x44C;&#x441;&#x44F;.</p><p>&#x415;&#x441;&#x43B;&#x438; &#x43E;&#x431;&#x440;&#x430;&#x442;&#x438;&#x442;&#x44C;&#x441;&#x44F; &#x43D;&#x430; 80 &#x43F;&#x43E;&#x440;&#x442; localhost</p><p><code>curl localhost</code>, &#x442;&#x43E; &#x43F;&#x43E;&#x43B;&#x443;&#x447;&#x438;&#x43C; <code>Simple app for test</code> . &#x41D;&#x435;&#x431;&#x43E;&#x43B;&#x44C;&#x448;&#x430;&#x44F; &#x437;&#x430;&#x434;&#x435;&#x440;&#x436;&#x43A;&#x430; &#x43D;&#x430; &#x441;&#x442;&#x430;&#x440;&#x442;&#x435; &#x43D;&#x430;&#x441; &#x43D;&#x435; &#x43F;&#x443;&#x433;&#x430;&#x435;&#x442;, &#x43F;&#x43E;&#x442;&#x43E;&#x43C;&#x443; &#x447;&#x442;&#x43E; &#x43F;&#x43E;&#x434;&#x440;&#x430;&#x437;&#x443;&#x43C;&#x435;&#x432;&#x430;&#x435;&#x442;&#x441;&#x44F; &#x447;&#x442;&#x43E; &#x43A; &#x441;&#x435;&#x440;&#x432;&#x438;&#x441;&#x44B; &#x43E;&#x431;&#x440;&#x430;&#x449;&#x430;&#x44E;&#x442;&#x441;&#x44F; &#x43D;&#x435; &#x447;&#x430;&#x441;&#x442;&#x43E;.</p><p>&#x427;&#x442;&#x43E; &#x44F; &#x43D;&#x435; &#x443;&#x441;&#x43F;&#x435;&#x43B; &#x441;&#x434;&#x435;&#x43B;&#x430;&#x442;&#x44C; &#x2014; &#x43E;&#x442;&#x441;&#x43B;&#x435;&#x436;&#x438;&#x432;&#x430;&#x43D;&#x438;&#x435; &#x442;&#x440;&#x430;&#x444;&#x438;&#x43A;&#x430; &#x437;&#x430; &#x43E;&#x43F;&#x440;&#x435;&#x434;&#x435;&#x43B;&#x435;&#x43D;&#x43D;&#x44B;&#x439; &#x43C;&#x43E;&#x43C;&#x435;&#x43D;&#x442; &#x432;&#x440;&#x435;&#x43C;&#x435;&#x43D;&#x438; &#x441; &#x446;&#x435;&#x43B;&#x44C;&#x44E; &#x43E;&#x441;&#x442;&#x430;&#x43D;&#x43E;&#x432;&#x438;&#x442;&#x44C; &#x441;&#x435;&#x440;&#x432;&#x438;&#x441;. &#x41F;&#x43E; &#x438;&#x434;&#x435;&#x435; &#x44D;&#x442;&#x43E; &#x43F;&#x440;&#x43E;&#x441;&#x442;&#x43E; &#x43F;&#x430;&#x440;&#x441;&#x438;&#x43D;&#x433; &#x43B;&#x43E;&#x433;&#x43E;&#x432;, &#x435;&#x441;&#x43B;&#x438; &#x437;&#x430; &#x43F;&#x43E;&#x441;&#x43B;&#x435;&#x434;&#x43D;&#x438;&#x435; N &#x43C;&#x438;&#x43D;&#x443;&#x442; &#x43D;&#x438;&#x447;&#x435;&#x433;&#x43E; &#x43D;&#x435; &#x431;&#x44B;&#x43B;&#x43E;, &#x442;&#x43E; &#x43E;&#x441;&#x442;&#x430;&#x43D;&#x430;&#x432;&#x43B;&#x438;&#x432;&#x430;&#x435;&#x43C; &#x441;&#x435;&#x440;&#x432;&#x438;&#x441; &#x441; &#x43A;&#x43E;&#x43D;&#x442;&#x435;&#x439;&#x43D;&#x435;&#x440;&#x43E;&#x43C;. &#x415;&#x441;&#x43B;&#x438; &#x43C;&#x44B; &#x441;&#x43E;&#x431;&#x435;&#x440;&#x435;&#x43C;&#x441;&#x44F; &#x434;&#x435;&#x43B;&#x430;&#x442;&#x44C; &#x442;&#x430;&#x43A;&#x43E;&#x435; &#x440;&#x435;&#x448;&#x435;&#x43D;&#x438;&#x435; &#x43D;&#x430; &#x43D;&#x430;&#x448;&#x438;&#x445; 250+ &#x43F;&#x440;&#x43E;&#x435;&#x43A;&#x442;&#x43E;&#x432;, &#x442;&#x43E; &#x43E;&#x431;&#x44F;&#x437;&#x430;&#x442;&#x435;&#x43B;&#x44C;&#x43D;&#x43E; &#x43D;&#x430;&#x43F;&#x438;&#x448;&#x443;.</p><p>Stay tuned&#x2026;</p><p>P.S. &#x413;&#x434;&#x435; &#x447;&#x442;&#x43E; &#x43F;&#x43E;&#x434;&#x441;&#x43C;&#x430;&#x442;&#x440;&#x438;&#x432;&#x430;&#x43B;:</p><ol><li><a href="http://0pointer.de/blog/projects/socket-activated-containers.html?ref=igkuz.ru" rel="noopener nofollow">&#x41E;&#x442; &#x440;&#x430;&#x437;&#x440;&#x430;&#x431;&#x43E;&#x442;&#x447;&#x438;&#x43A;&#x430; systemd &#x43F;&#x440;&#x43E; &#x430;&#x43A;&#x442;&#x438;&#x432;&#x430;&#x446;&#x438;&#x44E; &#x43A;&#x43E;&#x43D;&#x442;&#x435;&#x439;&#x43D;&#x435;&#x440;&#x43E;&#x432;.</a></li><li><a href="http://ahmet2mir.eu/blog/2015/python_ssl_sockets_and_systemd_activation/?ref=igkuz.ru" rel="noopener nofollow">&#x42D;&#x442;&#x43E;</a> &#x43D;&#x430; Python, &#x43D;&#x43E; &#x43C;&#x43E;&#x436;&#x43D;&#x43E; &#x43F;&#x43E;&#x441;&#x43C;&#x43E;&#x442;&#x440;&#x435;&#x442;&#x44C; &#x43A;&#x430;&#x43A; &#x43F;&#x440;&#x43E;&#x431;&#x440;&#x430;&#x441;&#x44B;&#x432;&#x430;&#x435;&#x442;&#x441;&#x44F; Socket &#x438;&#x437; Systemd</li><li><a href="http://ku1ik.com/2012/01/21/systemd-socket-activation-and-ruby.html?ref=igkuz.ru" rel="noopener nofollow">&#x410; &#x44D;&#x442;&#x43E; &#x43F;&#x440;&#x438;&#x43C;&#x435;&#x440; &#x43D;&#x430; Ruby &#x43A;&#x430;&#x43A; &#x440;&#x430;&#x431;&#x43E;&#x442;&#x430;&#x442;&#x44C; &#x441; &#x441;&#x43E;&#x43A;&#x435;&#x442;&#x43E;&#x43C; Sytemd</a></li><li><a href="https://developer.atlassian.com/blog/2015/03/docker-systemd-socket-activation/?ref=igkuz.ru" rel="noopener nofollow">&#x41E;&#x442;&#x43A;&#x443;&#x434;&#x430; &#x432;&#x437;&#x44F;&#x43B; &#x433;&#x438;&#x444;&#x43A;&#x443;</a></li></ol>]]></content:encoded></item><item><title><![CDATA[Переезд]]></title><description><![CDATA[<blockquote>&#x418;&#x437;&#x43D;&#x430;&#x447;&#x430;&#x43B;&#x44C;&#x43D;&#x43E; &#x431;&#x44B;&#x43B;&#x43E; &#x43E;&#x43F;&#x443;&#x431;&#x43B;&#x438;&#x43A;&#x43E;&#x432;&#x430;&#x43D;&#x43E; &#x432; &#x43C;&#x43E;&#x435;&#x43C; <a href="https://medium.com/@igkuz/moving-out-42290a7cb7e0?ref=igkuz.ru">medium &#x431;&#x43B;&#x43E;&#x433;&#x435;</a>.</blockquote><p>&#x412; &#x434;&#x435;&#x43A;&#x430;&#x431;&#x440;&#x435; 2017 &#x43C;&#x44B; &#x440;&#x435;</p>]]></description><link>https://igkuz.ru/moving-out/</link><guid isPermaLink="false">5e9209026d9007355d8bde82</guid><category><![CDATA[devops]]></category><category><![CDATA[Data Center]]></category><category><![CDATA[System Administration]]></category><dc:creator><![CDATA[Igor Kuznetsov]]></dc:creator><pubDate>Tue, 06 Feb 2018 08:00:00 GMT</pubDate><media:content url="https://igkuz.ru/content/images/2020/04/moving-out-of-state-optimize-2.gif" medium="image"/><content:encoded><![CDATA[<blockquote>&#x418;&#x437;&#x43D;&#x430;&#x447;&#x430;&#x43B;&#x44C;&#x43D;&#x43E; &#x431;&#x44B;&#x43B;&#x43E; &#x43E;&#x43F;&#x443;&#x431;&#x43B;&#x438;&#x43A;&#x43E;&#x432;&#x430;&#x43D;&#x43E; &#x432; &#x43C;&#x43E;&#x435;&#x43C; <a href="https://medium.com/@igkuz/moving-out-42290a7cb7e0?ref=igkuz.ru">medium &#x431;&#x43B;&#x43E;&#x433;&#x435;</a>.</blockquote><img src="https://igkuz.ru/content/images/2020/04/moving-out-of-state-optimize-2.gif" alt="&#x41F;&#x435;&#x440;&#x435;&#x435;&#x437;&#x434;"><p>&#x412; &#x434;&#x435;&#x43A;&#x430;&#x431;&#x440;&#x435; 2017 &#x43C;&#x44B; &#x440;&#x435;&#x448;&#x438;&#x43B;&#x438; &#x441;&#x43C;&#x435;&#x43D;&#x438;&#x442;&#x44C; &#x434;&#x430;&#x442;&#x430;&#x446;&#x435;&#x43D;&#x442;&#x440; (&#x414;&#x426;). &#x420;&#x435;&#x448;&#x435;&#x43D;&#x438;&#x435; &#x441;&#x435;&#x440;&#x44C;&#x435;&#x437;&#x43D;&#x43E;&#x435; &#x438; &#x43F;&#x440;&#x438;&#x43D;&#x438;&#x43C;&#x430;&#x43B;&#x43E;&#x441;&#x44C; &#x438;&#x437;-&#x437;&#x430; 2&#x445; &#x43F;&#x440;&#x438;&#x447;&#x438;&#x43D;. &#x41E;&#x442;&#x441;&#x443;&#x442;&#x441;&#x442;&#x432;&#x438;&#x435; &#x437;&#x430;&#x449;&#x438;&#x442;&#x44B; &#x43E;&#x442; DDoS &#x430;&#x442;&#x430;&#x43A; &#x438; &#x446;&#x435;&#x43D;&#x43D;&#x438;&#x43A;. &#x41F;&#x440;&#x43E; &#x442;&#x43E; &#x43A;&#x430;&#x43A; &#x43A;&#x43B;&#x430;&#x441;&#x441;&#x43D;&#x43E; &#x414;&#x426; &#x43D;&#x430;&#x43C; &#x43F;&#x43E;&#x43C;&#x43E;&#x433;(&#x43D;&#x435;&#x442;) &#x432;&#x43E; &#x432;&#x440;&#x435;&#x43C;&#x44F; &#x430;&#x442;&#x430;&#x43A;&#x438; &#x44F; &#x443;&#x436;&#x435; <a href="https://medium.com/@igkuz/%D0%BE%D1%82%D1%80%D0%B0%D0%B6%D0%B0%D1%8F-ddos-f80c1737c19b?ref=igkuz.ru" rel="noopener">&#x440;&#x430;&#x441;&#x441;&#x43A;&#x430;&#x437;&#x44B;&#x432;&#x430;&#x43B;,</a> &#x43D;&#x443; &#x438; &#x441;&#x43D;&#x438;&#x437;&#x438;&#x442;&#x44C; &#x437;&#x430;&#x442;&#x440;&#x430;&#x442;&#x44B; &#x43D;&#x430; &#x438;&#x43D;&#x444;&#x440;&#x430;&#x441;&#x442;&#x440;&#x443;&#x43A;&#x442;&#x443;&#x440;&#x443; &#x43D;&#x435; &#x43F;&#x43E;&#x442;&#x435;&#x440;&#x44F;&#x432; &#x432; &#x43F;&#x440;&#x43E;&#x438;&#x437;&#x432;&#x43E;&#x434;&#x438;&#x442;&#x435;&#x43B;&#x44C;&#x43D;&#x43E;&#x441;&#x442;&#x438; &#x44D;&#x442;&#x43E; challenge.</p><p>&#x412;&#x430;&#x436;&#x43D;&#x44B;&#x435; &#x440;&#x435;&#x448;&#x435;&#x43D;&#x438;&#x44F; &#x432; &#x43A;&#x43E;&#x43C;&#x43F;&#x430;&#x43D;&#x438;&#x438; &#x43D;&#x435; &#x43F;&#x440;&#x438;&#x43D;&#x438;&#x43C;&#x430;&#x44E;&#x442;&#x441;&#x44F; &#x43E;&#x434;&#x43D;&#x438;&#x43C; &#x447;&#x435;&#x43B;&#x43E;&#x432;&#x435;&#x43A;&#x43E;&#x43C; &#x438; &#x434;&#x43E;&#x43B;&#x436;&#x43D;&#x44B; &#x431;&#x44B;&#x442;&#x44C; &#x445;&#x43E;&#x440;&#x43E;&#x448;&#x43E; &#x430;&#x440;&#x433;&#x443;&#x43C;&#x435;&#x43D;&#x442;&#x438;&#x440;&#x43E;&#x432;&#x430;&#x43D;&#x44B;.</p><h2 id="-">&#x41A;&#x430;&#x43A; &#x437;&#x430;&#x449;&#x438;&#x449;&#x430;&#x43B; &#x440;&#x435;&#x448;&#x435;&#x43D;&#x438;&#x435; &#x43F;&#x435;&#x440;&#x435;&#x434; &#x440;&#x443;&#x43A;&#x43E;&#x432;&#x43E;&#x434;&#x441;&#x442;&#x432;&#x43E;&#x43C;</h2><p>1. &#x41F;&#x440;&#x43E;&#x432;&#x435;&#x43B; &#x438;&#x441;&#x441;&#x43B;&#x435;&#x434;&#x43E;&#x432;&#x430;&#x43D;&#x438;&#x435; &#x43D;&#x435;&#x441;&#x43A;&#x43E;&#x43B;&#x44C;&#x43A;&#x438;&#x445; &#x432;&#x435;&#x43D;&#x434;&#x43E;&#x440;&#x43E;&#x432;<br>2. &#x421;&#x43E;&#x441;&#x442;&#x430;&#x432;&#x438;&#x43B; &#x442;&#x430;&#x431;&#x43B;&#x438;&#x446;&#x443; +/- &#x43D;&#x43E;&#x432;&#x43E;&#x433;&#x43E; &#x432;&#x435;&#x43D;&#x434;&#x43E;&#x440;&#x430;<br>3. &#x41F;&#x43E;&#x441;&#x447;&#x438;&#x442;&#x430;&#x43B; &#x43D;&#x43E;&#x432;&#x443;&#x44E; &#x441;&#x442;&#x43E;&#x438;&#x43C;&#x43E;&#x441;&#x442;&#x44C; &#x432;&#x43B;&#x430;&#x434;&#x435;&#x43D;&#x438;&#x44F; (TCO &#x2014; Total Cost of Ownership)<br>4. &#x41F;&#x43E;&#x441;&#x447;&#x438;&#x442;&#x430;&#x43B; &#x441;&#x442;&#x43E;&#x438;&#x43C;&#x43E;&#x441;&#x442;&#x44C; &#x43F;&#x435;&#x440;&#x435;&#x435;&#x437;&#x434;&#x430;. &#x42D;&#x442;&#x43E; &#x447;&#x435;&#x43B;&#x43E;&#x432;&#x435;&#x43A;&#x43E;-&#x447;&#x430;&#x441;&#x44B;, &#x432;&#x43E;&#x437;&#x43C;&#x43E;&#x436;&#x43D;&#x44B;&#x439; &#x43F;&#x440;&#x43E;&#x441;&#x442;&#x43E;&#x439; &#x43F;&#x43E; &#x434;&#x440;&#x443;&#x433;&#x438;&#x43C; &#x437;&#x430;&#x434;&#x430;&#x447;&#x430;&#x43C;, &#x440;&#x438;&#x441;&#x43A;&#x438; &#x43D;&#x430; &#x447;&#x430;&#x441;&#x442;&#x438;&#x447;&#x43D;&#x443;&#x44E; &#x43F;&#x43E;&#x442;&#x435;&#x440;&#x44E; &#x440;&#x430;&#x431;&#x43E;&#x442;&#x43E;&#x441;&#x43F;&#x43E;&#x441;&#x43E;&#x431;&#x43D;&#x43E;&#x441;&#x442;&#x438; &#x441;&#x438;&#x441;&#x442;&#x435;&#x43C;&#x44B; &#x438;&#x43B;&#x438; &#x43F;&#x43E;&#x43B;&#x43D;&#x44B;&#x439; &#x432;&#x44B;&#x445;&#x43E;&#x434; &#x438;&#x437; &#x441;&#x442;&#x440;&#x43E;&#x44F; &#x441;&#x438;&#x441;&#x442;&#x435;&#x43C;&#x44B;<br>5. &#x421;&#x43E;&#x441;&#x442;&#x430;&#x432;&#x438;&#x43B; &#x43F;&#x43B;&#x430;&#x43D; &#x43F;&#x435;&#x440;&#x435;&#x435;&#x437;&#x434;&#x430;<br>5. &#x41E;&#x444;&#x43E;&#x440;&#x43C;&#x438;&#x43B; &#x432;&#x44B;&#x448;&#x435;&#x43F;&#x435;&#x440;&#x435;&#x447;&#x438;&#x441;&#x43B;&#x435;&#x43D;&#x43D;&#x44B;&#x435; &#x43F;&#x443;&#x43D;&#x43A;&#x442;&#x44B; &#x432; &#x43D;&#x430;&#x431;&#x43E;&#x440; &#x441;&#x43B;&#x43E;&#x432; &#x438; &#x442;&#x430;&#x431;&#x43B;&#x438;&#x446; Excel<br>6. &#x41D;&#x430;&#x43F;&#x438;&#x441;&#x430;&#x43B; &#x43F;&#x438;&#x441;&#x44C;&#x43C;&#x43E; &#x43D;&#x430; &#x432;&#x441;&#x435;&#x445; &#x437;&#x430;&#x438;&#x43D;&#x442;&#x435;&#x440;&#x435;&#x441;&#x43E;&#x432;&#x430;&#x43D;&#x43D;&#x44B;&#x445;</p><p>&#x41D;&#x430; &#x447;&#x442;&#x43E; &#x43E;&#x431;&#x440;&#x430;&#x449;&#x430;&#x44E;&#x442; &#x432;&#x43D;&#x438;&#x43C;&#x430;&#x43D;&#x438;&#x435;:</p><ul><li>CFO &#x2014; &#x43F;&#x440;&#x43E;&#x444;&#x438;&#x442;/&#x43F;&#x43E;&#x442;&#x435;&#x440;&#x44E; &#x432; &#x434;&#x435;&#x43D;&#x44C;&#x433;&#x430;&#x445;</li><li>CEO &#x2014; &#x440;&#x435;&#x43F;&#x443;&#x442;&#x430;&#x446;&#x438;&#x43E;&#x43D;&#x43D;&#x44B;&#x435; &#x440;&#x438;&#x441;&#x43A;&#x438; &#x438;&#x437;-&#x437;&#x430; &#x43F;&#x440;&#x43E;&#x441;&#x442;&#x43E;&#x44F; &#x441;&#x438;&#x441;&#x442;&#x435;&#x43C;&#x44B;, &#x43A;&#x430;&#x43A; &#x43F;&#x440;&#x43E;&#x441;&#x442;&#x43E;&#x439; &#x43F;&#x43E; &#x434;&#x440;&#x443;&#x433;&#x438;&#x43C; &#x437;&#x430;&#x434;&#x430;&#x447;&#x430;&#x43C; &#x437;&#x430;&#x442;&#x440;&#x43E;&#x43D;&#x435;&#x442; &#x431;&#x438;&#x437;&#x43D;&#x435;&#x441; &#x432; &#x446;&#x435;&#x43B;&#x43E;&#x43C;, &#x446;&#x435;&#x43B;&#x435;&#x441;&#x43E;&#x43E;&#x431;&#x440;&#x430;&#x437;&#x43D;&#x43E;&#x441;&#x442;&#x44C; &#x43F;&#x435;&#x440;&#x435;&#x435;&#x437;&#x434;&#x430; &#x438;&#x43C;&#x435;&#x43D;&#x43D;&#x43E; &#x441;&#x435;&#x439;&#x447;&#x430;&#x441;</li></ul><h2 id="--1">&#x41A;&#x430;&#x43A; &#x432;&#x44B;&#x431;&#x440;&#x430;&#x442;&#x44C; &#x414;&#x426;</h2><p>&#x412; &#x43C;&#x43E;&#x435;&#x43C; &#x441;&#x43B;&#x443;&#x447;&#x430;&#x435; &#x432;&#x441;&#x451; &#x431;&#x44B;&#x43B;&#x43E; &#x434;&#x43E;&#x441;&#x442;&#x430;&#x442;&#x43E;&#x447;&#x43D;&#x43E; &#x43F;&#x440;&#x43E;&#x441;&#x442;&#x43E;, &#x43F;&#x43E;&#x442;&#x43E;&#x43C;&#x443; &#x447;&#x442;&#x43E; &#x443; &#x43D;&#x430;&#x441; &#x443;&#x436;&#x435; &#x431;&#x44B;&#x43B;&#x430; &#x447;&#x430;&#x441;&#x442;&#x44C; &#x438;&#x43D;&#x444;&#x440;&#x430;&#x441;&#x442;&#x440;&#x443;&#x43A;&#x442;&#x443;&#x440;&#x44B; &#x432; &#x44D;&#x442;&#x43E;&#x43C; &#x414;&#x426;. &#x41D;&#x43E; &#x441;&#x440;&#x430;&#x432;&#x43D;&#x435;&#x43D;&#x438;&#x44F; &#x441; &#x434;&#x440;&#x443;&#x433;&#x438;&#x43C;&#x438; &#x445;&#x43E;&#x441;&#x442;&#x438;&#x43D;&#x433;&#x430;&#x43C; &#x43C;&#x44B; &#x441; &#x441;&#x438;&#x441;&#x442;&#x435;&#x43C;&#x43D;&#x44B;&#x43C; &#x430;&#x434;&#x43C;&#x438;&#x43D;&#x438;&#x441;&#x442;&#x440;&#x430;&#x442;&#x43E;&#x440;&#x43E;&#x43C; &#x442;&#x435;&#x43C; &#x43D;&#x435; &#x43C;&#x435;&#x43D;&#x435;&#x435; &#x43F;&#x440;&#x43E;&#x432;&#x43E;&#x434;&#x438;&#x43B;&#x438;.</p><p>&#x41F;&#x440;&#x438;&#x43E;&#x440;&#x438;&#x442;&#x435;&#x442;&#x44B; &#x432; &#x441;&#x43F;&#x438;&#x441;&#x43A;&#x435; &#x440;&#x430;&#x441;&#x441;&#x442;&#x430;&#x432;&#x44C;&#x442;&#x435; &#x441;&#x430;&#x43C;&#x438;:</p><ol><li>&#x413;&#x435;&#x43E;&#x433;&#x440;&#x430;&#x444;&#x438;&#x447;&#x435;&#x441;&#x43A;&#x43E;&#x435; &#x440;&#x430;&#x441;&#x43F;&#x43E;&#x43B;&#x43E;&#x436;&#x435;&#x43D;&#x438;&#x435;. &#x427;&#x435;&#x43C; &#x431;&#x43B;&#x438;&#x436;&#x435;, &#x442;&#x435;&#x43C; &#x43B;&#x443;&#x447;&#x448;&#x435;, &#x43D;&#x43E; &#x43D;&#x435; &#x420;&#x43E;&#x441;&#x441;&#x438;&#x44F; &#x1F60F;</li><li>&#x421;&#x442;&#x43E;&#x438;&#x43C;&#x43E;&#x441;&#x442;&#x44C; &#x43E;&#x431;&#x43E;&#x440;&#x443;&#x434;&#x43E;&#x432;&#x430;&#x43D;&#x438;&#x44F;. &#x414;&#x435;&#x448;&#x435;&#x432;&#x43E;, &#x43D;&#x435; &#x432;&#x441;&#x435;&#x433;&#x434;&#x430; &#x445;&#x43E;&#x440;&#x43E;&#x448;&#x43E;, &#x43D;&#x443;&#x436;&#x43D;&#x43E; &#x441;&#x43C;&#x43E;&#x442;&#x440;&#x435;&#x442;&#x44C; &#x43D;&#x430; &#x445;&#x430;&#x440;&#x430;&#x43A;&#x442;&#x435;&#x440;&#x438;&#x441;&#x442;&#x438;&#x43A;&#x438;.</li><li>&#x425;&#x430;&#x440;&#x430;&#x43A;&#x442;&#x435;&#x440;&#x438;&#x441;&#x442;&#x438;&#x43A;&#x438; &#x43E;&#x431;&#x43E;&#x440;&#x443;&#x434;&#x43E;&#x432;&#x430;&#x43D;&#x438;&#x44F;. &#x414;&#x430;&#x442;&#x430; &#x432;&#x44B;&#x43F;&#x443;&#x441;&#x43A;&#x430; &#x43F;&#x440;&#x43E;&#x446;&#x435;&#x441;&#x441;&#x43E;&#x440;&#x43E;&#x432;, &#x438;&#x445; &#x447;&#x430;&#x441;&#x442;&#x43E;&#x442;&#x430;. &#x41E;&#x431;&#x44A;&#x435;&#x43C; &#x43E;&#x43F;&#x435;&#x440;&#x430;&#x442;&#x438;&#x432;&#x43D;&#x43E;&#x439; &#x43F;&#x430;&#x43C;&#x44F;&#x442;&#x438; &#x438; &#x432;&#x43E;&#x437;&#x43C;&#x43E;&#x436;&#x43D;&#x43E;&#x441;&#x442;&#x44C; &#x434;&#x43B;&#x44F; &#x440;&#x430;&#x441;&#x448;&#x438;&#x440;&#x435;&#x43D;&#x438;&#x44F;. SSD/HDD, &#x432;&#x43E;&#x437;&#x43C;&#x43E;&#x436;&#x43D;&#x43E;&#x441;&#x442;&#x44C; RAID &#x441; &#x431;&#x430;&#x442;&#x430;&#x440;&#x435;&#x439;&#x43A;&#x43E;&#x439;, &#x441;&#x435;&#x442;&#x435;&#x432;&#x44B;&#x435; &#x43A;&#x430;&#x440;&#x442;&#x44B; &#x438; &#x432;&#x445;&#x43E;&#x434;&#x44F;&#x449;&#x438;&#x439; &#x43A;&#x430;&#x43D;&#x430;&#x43B; (10Gb/s &#x2014; &#x43E;&#x442;&#x43B;&#x438;&#x447;&#x43D;&#x43E;, 1Gb/s &#x2014; &#x43F;&#x43E;&#x439;&#x434;&#x435;&#x442;).</li><li>&#x424;&#x443;&#x43D;&#x43A;&#x446;&#x438;&#x43E;&#x43D;&#x430;&#x43B; &#x43F;&#x43E; &#x43D;&#x430;&#x441;&#x442;&#x440;&#x43E;&#x439;&#x43A;&#x435; &#x441;&#x435;&#x442;&#x438;. &#x412; Softlayer &#x43C;&#x43E;&#x436;&#x43D;&#x43E; &#x441;&#x434;&#x435;&#x43B;&#x430;&#x442;&#x44C; &#x445;&#x43E;&#x440;&#x43E;&#x448;&#x438;&#x439; <a href="http://www.linuxvirtualserver.org/?ref=igkuz.ru" rel="noopener nofollow">LVS</a> &#x438; &#x443;&#x442;&#x438;&#x43B;&#x438;&#x437;&#x438;&#x440;&#x43E;&#x432;&#x430;&#x442;&#x44C; &#x43F;&#x43E; &#x444;&#x430;&#x43A;&#x442;&#x443; &#x43A;&#x430;&#x43D;&#x430;&#x43B; &#x43A;&#x430;&#x436;&#x434;&#x43E;&#x433;&#x43E; &#x441;&#x435;&#x440;&#x432;&#x435;&#x440;&#x430;, &#x43F;&#x43E;&#x43B;&#x443;&#x447;&#x430;&#x44F; 1xN Gb/s (&#x433;&#x434;&#x435; N &#x2014; &#x43A;&#x43E;&#x43B;-&#x432;&#x43E; &#x441;&#x435;&#x440;&#x432;&#x435;&#x440;&#x43E;&#x432;). &#x412; Hetzner IP &#x43F;&#x440;&#x438;&#x431;&#x438;&#x442; &#x43A; &#x441;&#x435;&#x440;&#x432;&#x435;&#x440;&#x443; &#x438; &#x441; &#x434;&#x440;&#x443;&#x433;&#x43E;&#x439; &#x43C;&#x430;&#x448;&#x438;&#x43D;&#x44B; &#x43E;&#x442;&#x432;&#x435;&#x447;&#x430;&#x442;&#x44C; &#x43D;&#x435;&#x43B;&#x44C;&#x437;&#x44F;. Failover IP &#x43F;&#x435;&#x440;&#x435;&#x43C;&#x435;&#x449;&#x430;&#x435;&#x442;&#x441;&#x44F; &#x442;&#x43E;&#x43B;&#x44C;&#x43A;&#x43E; &#x447;&#x435;&#x440;&#x435;&#x437; &#x437;&#x430;&#x43F;&#x440;&#x43E;&#x441; &#x432; API.</li><li>&#x417;&#x430;&#x449;&#x438;&#x442;&#x430; &#x43E;&#x442; DDoS. &#x414;&#x430;, &#x432; 2018 &#x431;&#x435;&#x437; &#x43D;&#x435;&#x451; &#x43D;&#x438;&#x43A;&#x443;&#x434;&#x430;, &#x43E;&#x441;&#x43E;&#x431;&#x435;&#x43D;&#x43D;&#x43E; &#x435;&#x441;&#x43B;&#x438; &#x432;&#x44B; &#x438;&#x43D;&#x442;&#x435;&#x440;&#x43D;&#x435;&#x442; &#x438;&#x437;&#x434;&#x430;&#x43D;&#x438;&#x435;. &#x415;&#x441;&#x442;&#x44C; &#x43A;&#x43E;&#x43D;&#x435;&#x447;&#x43D;&#x43E; &#x431;&#x435;&#x441;&#x43F;&#x43B;&#x430;&#x442;&#x43D;&#x44B;&#x435; CloudFlare &#x438; Google Shield, &#x43D;&#x43E; &#x432;&#x44B; &#x442;&#x435;&#x440;&#x44F;&#x435;&#x442;&#x435; &#x432; &#x43A;&#x43E;&#x43D;&#x442;&#x440;&#x43E;&#x43B;&#x435;. &#x415;&#x441;&#x43B;&#x438; &#x414;&#x426; &#x43C;&#x43E;&#x436;&#x435;&#x442; &#x437;&#x430;&#x449;&#x438;&#x442;&#x438;&#x442;&#x44C; &#x432;&#x430;&#x441; &#x43D;&#x430; &#x441;&#x435;&#x442;&#x435;&#x432;&#x44B;&#x445; &#x443;&#x440;&#x43E;&#x432;&#x43D;&#x44F;&#x445;, &#x442;&#x43E; &#x43B;&#x443;&#x447;&#x448;&#x435; &#x432;&#x44B;&#x431;&#x440;&#x430;&#x442;&#x44C; &#x442;&#x430;&#x43A;&#x43E;&#x439; &#x414;&#x426;.</li><li>&#x412;&#x43A;&#x43B;&#x44E;&#x447;&#x435;&#x43D;&#x43D;&#x44B;&#x439; &#x432; &#x43F;&#x430;&#x43A;&#x435;&#x442; &#x441;&#x435;&#x442;&#x435;&#x432;&#x43E;&#x439; &#x442;&#x440;&#x430;&#x444;&#x438;&#x43A;. &#x41E;&#x431;&#x43E;&#x440;&#x443;&#x434;&#x43E;&#x432;&#x430;&#x43D;&#x438;&#x435; &#x431;&#x44B;&#x441;&#x442;&#x440;&#x43E; &#x443;&#x441;&#x442;&#x430;&#x440;&#x435;&#x432;&#x430;&#x435;&#x442;, &#x430; &#x437;&#x430; &#x442;&#x440;&#x430;&#x444;&#x438;&#x43A; &#x432; &#x43F;&#x43E;&#x441;&#x43B;&#x435;&#x434;&#x43D;&#x44F;&#x44F; &#x432;&#x440;&#x435;&#x43C;&#x44F; &#x431;&#x435;&#x440;&#x443;&#x442; &#x434;&#x43E;&#x440;&#x43E;&#x433;&#x43E;. &#x427;&#x435;&#x43C; &#x431;&#x43E;&#x43B;&#x44C;&#x448;&#x435; &#x432; &#x431;&#x430;&#x437;&#x43E;&#x432;&#x43E;&#x43C; &#x43F;&#x430;&#x43A;&#x435;&#x442;&#x435;, &#x442;&#x435;&#x43C; &#x43B;&#x443;&#x447;&#x448;&#x435;.</li><li>&#x41D;&#x430;&#x43B;&#x438;&#x447;&#x438;&#x435; &#x440;&#x443;&#x441;&#x441;&#x43A;&#x43E;&#x433;&#x43E;&#x432;&#x43E;&#x440;&#x44F;&#x449;&#x435;&#x439; &#x43F;&#x43E;&#x434;&#x434;&#x435;&#x440;&#x436;&#x43A;&#x438;. &#x414;&#x430;, &#x43D;&#x430; &#x430;&#x43D;&#x433;&#x43B; &#x43C;&#x43E;&#x436;&#x43D;&#x43E; &#x441;&#x43F;&#x43E;&#x43A;&#x43E;&#x439;&#x43D;&#x43E; &#x432;&#x441;&#x451; &#x443;&#x437;&#x43D;&#x430;&#x442;&#x44C;, &#x43D;&#x43E; &#x43D;&#x430;&#x43B;&#x430;&#x436;&#x435;&#x43D;&#x43D;&#x44B;&#x439; &#x43A;&#x43E;&#x43D;&#x442;&#x430;&#x43A;&#x442; &#x441; &#x43C;&#x435;&#x43D;&#x435;&#x434;&#x436;&#x435;&#x440;&#x43E;&#x43C; &#x432; &#x414;&#x426; &#x43D;&#x430;&#x43C;&#x43D;&#x43E;&#x433;&#x43E; &#x43F;&#x43E;&#x43B;&#x435;&#x437;&#x43D;&#x435;&#x435;. &#x41C;&#x43E;&#x436;&#x43D;&#x43E; &#x443;&#x437;&#x43D;&#x430;&#x442;&#x44C; &#x43C;&#x43D;&#x43E;&#x433;&#x43E; &#x43F;&#x43E;&#x434;&#x440;&#x43E;&#x431;&#x43D;&#x43E;&#x441;&#x442;&#x435;&#x439; &#x438; &#x43F;&#x43E;&#x43B;&#x443;&#x447;&#x438;&#x442;&#x44C; &#x445;&#x43E;&#x440;&#x43E;&#x448;&#x443;&#x44E; &#x43A;&#x43E;&#x43D;&#x441;&#x443;&#x43B;&#x44C;&#x442;&#x430;&#x446;&#x438;&#x44E; &#x43E; &#x442;&#x43E;&#x43C; &#x43A;&#x430;&#x43A; &#x43D;&#x430; &#x438;&#x445; &#x43C;&#x43E;&#x449;&#x43D;&#x43E;&#x441;&#x442;&#x44F;&#x445; &#x43F;&#x43E;&#x441;&#x442;&#x440;&#x43E;&#x438;&#x442;&#x44C; &#x43D;&#x443;&#x436;&#x43D;&#x443;&#x44E; &#x438;&#x43D;&#x444;&#x440;&#x430;&#x441;&#x442;&#x440;&#x443;&#x43A;&#x442;&#x443;&#x440;&#x443;.</li><li>&#x41E;&#x431;&#x43B;&#x430;&#x447;&#x43D;&#x44B;&#x435; &#x441;&#x435;&#x440;&#x432;&#x438;&#x441;&#x44B;. &#x423; &#x43D;&#x430;&#x441; &#x435;&#x441;&#x442;&#x44C; <a href="https://ceph.com/?ref=igkuz.ru" rel="noopener nofollow">Ceph</a> &#x434;&#x43B;&#x44F; &#x445;&#x440;&#x430;&#x43D;&#x435;&#x43D;&#x438;&#x44F; &#x438;&#x437;&#x43E;&#x431;&#x440;&#x430;&#x436;&#x435;&#x43D;&#x438;&#x439;, &#x435;&#x441;&#x43B;&#x438; &#x431;&#x44B; &#x43F;&#x43E;&#x445;&#x43E;&#x436;&#x435;&#x435; &#x440;&#x435;&#x448;&#x435;&#x43D;&#x438;&#x435; as a service &#x431;&#x44B;&#x43B;&#x43E; &#x443; &#x414;&#x426;, &#x442;&#x43E; &#x44F; &#x434;&#x443;&#x43C;&#x430;&#x44E; &#x432;&#x437;&#x44F;&#x43B; &#x431;&#x44B;. &#x41D;&#x43E; &#x43F;&#x43E;&#x43A;&#x430; &#x43F;&#x43E;&#x434;&#x434;&#x435;&#x440;&#x436;&#x438;&#x432;&#x430;&#x435;&#x43C; &#x441;&#x430;&#x43C;&#x438;.</li><li>&#x412;&#x44B;&#x434;&#x435;&#x43B;&#x435;&#x43D;&#x43D;&#x44B;&#x439; &#x43A;&#x430;&#x43D;&#x430;&#x43B; &#x441; &#x434;&#x440;&#x443;&#x433;&#x438;&#x43C;&#x438; &#x414;&#x426;. &#x41A;&#x430;&#x43A; &#x43F;&#x440;&#x430;&#x432;&#x438;&#x43B;&#x43E; &#x431;&#x43E;&#x43B;&#x44C;&#x448;&#x438;&#x435; &#x440;&#x435;&#x431;&#x44F;&#x442;&#x430; &#x43F;&#x440;&#x43E;&#x43A;&#x438;&#x434;&#x44B;&#x432;&#x430;&#x44E;&#x442; &#x441;&#x432;&#x43E;&#x438; &#x43A;&#x430;&#x431;&#x435;&#x43B;&#x438; &#x438;&#x43B;&#x438; &#x432;&#x44B;&#x43A;&#x443;&#x43F;&#x430;&#x44E;&#x442; &#x43C;&#x43E;&#x449;&#x43D;&#x43E;&#x441;&#x442;&#x44C;, &#x447;&#x442;&#x43E;&#x431;&#x44B; &#x434;&#x430;&#x442;&#x44C; &#x43A;&#x440;&#x443;&#x43F;&#x43D;&#x44B;&#x43C; &#x43A;&#x43B;&#x438;&#x435;&#x43D;&#x442;&#x430;&#x43C; &#x432;&#x43E;&#x437;&#x43C;&#x43E;&#x436;&#x43D;&#x43E;&#x441;&#x442;&#x44C; &#x43F;&#x435;&#x440;&#x435;&#x43A;&#x438;&#x434;&#x44B;&#x432;&#x430;&#x442;&#x44C; &#x431;&#x43E;&#x43B;&#x44C;&#x448;&#x438;&#x435; &#x43E;&#x431;&#x44A;&#x435;&#x43C;&#x44B; &#x434;&#x430;&#x43D;&#x43D;&#x44B;&#x445; &#x43C;&#x435;&#x436;&#x434;&#x443; &#x440;&#x430;&#x437;&#x43D;&#x44B;&#x43C;&#x438; &#x43F;&#x440;&#x43E;&#x432;&#x430;&#x439;&#x434;&#x435;&#x440;&#x430;&#x43C;.</li></ol><p>&#x41F;&#x43E;&#x441;&#x43B;&#x435; &#x44D;&#x442;&#x430;&#x43F;&#x430; &#x441;&#x43E;&#x433;&#x43B;&#x430;&#x441;&#x43E;&#x432;&#x430;&#x43D;&#x438;&#x439; &#x43C;&#x43E;&#x436;&#x43D;&#x43E; &#x43F;&#x440;&#x438;&#x441;&#x442;&#x443;&#x43F;&#x438;&#x442;&#x44C; &#x43A; &#x43F;&#x435;&#x440;&#x435;&#x435;&#x437;&#x434;&#x443;. &#x41E;&#x43F;&#x438;&#x441;&#x44B;&#x432;&#x430;&#x44E; &#x43B;&#x438;&#x447;&#x43D;&#x44B;&#x439; &#x43E;&#x43F;&#x44B;&#x442;:<br>1. &#x417;&#x430;&#x43A;&#x430;&#x437;&#x430;&#x43B;&#x438; &#x43C;&#x430;&#x448;&#x438;&#x43D;&#x44B; &#x43D;&#x443;&#x436;&#x43D;&#x43E;&#x439; &#x43A;&#x43E;&#x43D;&#x444;&#x438;&#x433;&#x443;&#x440;&#x430;&#x446;&#x438;&#x438;. &#x41E;&#x431;&#x44B;&#x447;&#x43D;&#x43E; 3 &#x440;&#x430;&#x431;&#x43E;&#x447;&#x438;&#x445; &#x434;&#x43D;&#x44F;, &#x43D;&#x43E; &#x432; &#x44D;&#x442;&#x43E;&#x442; &#x440;&#x430;&#x437; &#x434;&#x435;&#x43B;&#x430;&#x43B;&#x438; &#x43D;&#x435;&#x434;&#x435;&#x43B;&#x44E;, &#x441;&#x43F;&#x438;&#x441;&#x44B;&#x432;&#x430;&#x44E; &#x43D;&#x430; &#x43D;&#x435;&#x441;&#x442;&#x430;&#x43D;&#x434;&#x430;&#x440;&#x442;&#x43D;&#x44B;&#x439; &#x437;&#x430;&#x43F;&#x440;&#x43E;&#x441; (RAID &#x441; &#x431;&#x430;&#x442;&#x430;&#x440;&#x435;&#x439;&#x43A;&#x43E;&#x439;, &#x434;&#x43E;&#x43F;&#x43E;&#x43B;&#x43D;&#x438;&#x442;&#x435;&#x43B;&#x44C;&#x43D;&#x44B;&#x435; &#x441;&#x435;&#x442;&#x435;&#x432;&#x44B;&#x435;, failover IP, &#x434;&#x43E;&#x43F;&#x43E;&#x43B;&#x43D;&#x438;&#x442;&#x435;&#x43B;&#x44C;&#x43D;&#x430;&#x44F; &#x43F;&#x43E;&#x434;&#x441;&#x435;&#x442;&#x44C;).<br>2. &#x417;&#x430;&#x441;&#x435;&#x442;&#x430;&#x43F;&#x438;&#x43B;&#x438; &#x438;&#x43D;&#x444;&#x440;&#x430;&#x441;&#x442;&#x440;&#x443;&#x43A;&#x442;&#x443;&#x440;&#x443;. &#x41E;&#x431;&#x440;&#x430;&#x437;&#x44B; &#x432;&#x438;&#x440;&#x442;&#x443;&#x430;&#x43B;&#x44C;&#x43D;&#x44B;&#x445; &#x43C;&#x430;&#x448;&#x438;&#x43D;, &#x43D;&#x430;&#x441;&#x442;&#x440;&#x43E;&#x439;&#x43A;&#x430; &#x441;&#x435;&#x442;&#x435;&#x432;&#x44B;&#x445; &#x438;&#x43D;&#x442;&#x435;&#x440;&#x444;&#x435;&#x439;&#x441;&#x43E;&#x432;, &#x431;&#x430;&#x43B;&#x430;&#x43D;&#x441;&#x438;&#x440;&#x43E;&#x432;&#x43A;&#x430;, &#x43D;&#x435;&#x431;&#x43E;&#x43B;&#x44C;&#x448;&#x438;&#x435; &#x442;&#x435;&#x441;&#x442;&#x44B; &#x436;&#x435;&#x43B;&#x435;&#x437;&#x430;. (1,5&#x2013;2 &#x43D;&#x435;&#x434;&#x435;&#x43B;&#x438;)<br>3. &#x41F;&#x43E;&#x434;&#x433;&#x43E;&#x442;&#x43E;&#x432;&#x43A;&#x430; &#x43F;&#x440;&#x43E;&#x435;&#x43A;&#x442;&#x43E;&#x432; &#x43A; &#x43F;&#x435;&#x440;&#x435;&#x435;&#x437;&#x434;&#x443;. &#x41A; &#x44D;&#x442;&#x43E;&#x43C;&#x443; &#x43C;&#x43E;&#x43C;&#x435;&#x43D;&#x442;&#x443; &#x434;&#x43E;&#x43B;&#x436;&#x43D;&#x44B; &#x431;&#x44B;&#x442;&#x44C; &#x438;&#x437;&#x432;&#x435;&#x441;&#x442;&#x43D;&#x44B; &#x43F;&#x43E;&#x434;&#x441;&#x435;&#x442;&#x438;, &#x43E;&#x442;&#x43A;&#x430;&#x437;&#x43E;&#x443;&#x441;&#x442;&#x43E;&#x439;&#x447;&#x438;&#x432;&#x44B;&#x435; &#x430;&#x434;&#x440;&#x435;&#x441;&#x430; &#x434;&#x43B;&#x44F; &#x441;&#x435;&#x440;&#x432;&#x438;&#x441;&#x43E;&#x432; &#x438; &#x43E;&#x442;&#x442;&#x435;&#x441;&#x442;&#x438;&#x440;&#x43E;&#x432;&#x430;&#x43D;&#x44B; failover. (2 &#x434;&#x43D;&#x44F;)<br>4. &#x417;&#x430;&#x444;&#x438;&#x43A;&#x441;&#x438;&#x440;&#x43E;&#x432;&#x430;&#x43B;&#x438; &#x43F;&#x43B;&#x430;&#x43D; &#x43F;&#x435;&#x440;&#x435;&#x435;&#x437;&#x434;&#x430;. &#x42D;&#x442;&#x43E; &#x43F;&#x440;&#x43E;&#x441;&#x442;&#x43E; &#x43F;&#x43E;&#x441;&#x43B;&#x435;&#x434;&#x43E;&#x432;&#x430;&#x442;&#x435;&#x43B;&#x44C;&#x43D;&#x43E;&#x441;&#x442;&#x44C; &#x434;&#x435;&#x439;&#x441;&#x442;&#x432;&#x438;&#x439;, &#x447;&#x442;&#x43E;&#x431;&#x44B; &#x432;&#x43E; &#x432;&#x440;&#x435;&#x43C;&#x44F; &#x440;&#x430;&#x431;&#x43E;&#x442; &#x43D;&#x435; &#x437;&#x430;&#x434;&#x443;&#x43C;&#x44B;&#x432;&#x430;&#x442;&#x44C;&#x441;&#x44F; &#x43E; &#x441;&#x43B;&#x435;&#x434;&#x443;&#x44E;&#x449;&#x435;&#x43C; &#x448;&#x430;&#x433;&#x435; &#x438; &#x43D;&#x438;&#x447;&#x435;&#x433;&#x43E; &#x43D;&#x435; &#x437;&#x430;&#x431;&#x44B;&#x442;&#x44C;.<br>5. &#x421;&#x43E;&#x433;&#x43B;&#x430;&#x441;&#x43E;&#x432;&#x430;&#x43B;&#x438; &#x434;&#x430;&#x442;&#x443; &#x438; &#x432;&#x440;&#x435;&#x43C;&#x435;&#x43D;&#x43D;&#x43E;&#x435; &#x43E;&#x43A;&#x43D;&#x43E;. &#x421;&#x43E;&#x442;&#x440;&#x443;&#x434;&#x43D;&#x438;&#x43A;&#x438; &#x43D;&#x435; &#x445;&#x43E;&#x434;&#x44F;&#x442; &#x432; &#x43F;&#x440;&#x438;&#x43B;&#x43E;&#x436;&#x435;&#x43D;&#x438;&#x44F; &#x438; &#x43D;&#x438;&#x447;&#x435;&#x433;&#x43E; &#x43D;&#x435; &#x441;&#x43E;&#x437;&#x434;&#x430;&#x44E;&#x442;, &#x447;&#x442;&#x43E;&#x431;&#x44B; &#x438;&#x437;&#x431;&#x435;&#x436;&#x430;&#x442;&#x44C; &#x43B;&#x438;&#x448;&#x43D;&#x438;&#x445; &#x43F;&#x440;&#x43E;&#x431;&#x43B;&#x435;&#x43C;. &#x41C;&#x44B; &#x43F;&#x43E;&#x43A;&#x430; &#x43D;&#x435; Google &#x438; &#x434;&#x430;&#x436;&#x435; &#x43D;&#x435; VK, &#x43F;&#x43E;&#x44D;&#x442;&#x43E;&#x43C;&#x443; &#x43C;&#x43E;&#x436;&#x435;&#x43C; &#x441;&#x435;&#x431;&#x435; &#x43F;&#x43E;&#x437;&#x432;&#x43E;&#x43B;&#x438;&#x442;&#x44C;.</p><h2 id="--2">&#x41A;&#x430;&#x43A; &#x432;&#x44B;&#x433;&#x43B;&#x44F;&#x434;&#x438;&#x442; &#x441;&#x430;&#x43C; &#x43F;&#x435;&#x440;&#x435;&#x435;&#x437;&#x434;</h2><p>&#x427;&#x442;&#x43E; &#x443; &#x432;&#x430;&#x441; &#x434;&#x43E;&#x43B;&#x436;&#x43D;&#x43E; &#x431;&#x44B;&#x442;&#x44C; &#x43D;&#x430; &#x441;&#x442;&#x430;&#x440;&#x442;&#x435;:</p><ul><li>&#x41D;&#x430;&#x431;&#x43E;&#x440; &#x441;&#x435;&#x440;&#x44B;&#x445; IP &#x432;&#x441;&#x435;&#x445; &#x432;&#x438;&#x440;&#x442;&#x443;&#x430;&#x43B;&#x44C;&#x43D;&#x44B;&#x445; &#x43C;&#x430;&#x448;&#x438;&#x43D;</li><li>&#x41D;&#x430;&#x431;&#x43E;&#x440; highly available IP &#x434;&#x43B;&#x44F; &#x438;&#x43D;&#x444;&#x440;&#x430;&#x441;&#x442;&#x440;&#x443;&#x43A;&#x442;&#x443;&#x440;&#x43D;&#x44B;&#x445; &#x441;&#x435;&#x440;&#x432;&#x438;&#x441;&#x43E;&#x432; (Memcached, DB, Elastic, LoadBalancer, etc)</li><li>VPN &#x442;&#x443;&#x43D;&#x43D;&#x435;&#x43B;&#x438; &#x43C;&#x435;&#x436;&#x434;&#x443; &#x414;&#x426;</li><li>&#x41D;&#x430;&#x431;&#x43E;&#x440; &#x43A;&#x43E;&#x43D;&#x444;&#x438;&#x433;&#x43E;&#x432; &#x43F;&#x440;&#x438;&#x43B;&#x43E;&#x436;&#x435;&#x43D;&#x438;&#x439; &#x441; &#x43D;&#x43E;&#x432;&#x44B;&#x43C;&#x438; &#x430;&#x434;&#x440;&#x435;&#x441;&#x430;&#x43C;&#x438;</li><li>&#x421;&#x43F;&#x438;&#x441;&#x43E;&#x43A; &#x43A;&#x43E;&#x43C;&#x430;&#x43D;&#x434; &#x434;&#x43B;&#x44F; &#x441;&#x442;&#x430;&#x440;&#x442;&#x430;/&#x441;&#x442;&#x43E;&#x43F;&#x430; &#x43F;&#x440;&#x438;&#x43B;&#x43E;&#x436;&#x435;&#x43D;&#x438;&#x439;/&#x43E;&#x447;&#x435;&#x440;&#x435;&#x434;&#x435;&#x439;/&#x441;&#x435;&#x440;&#x432;&#x438;&#x441;&#x43E;&#x432; &#x43F;&#x43E;&#x434; &#x440;&#x443;&#x43A;&#x43E;&#x439;</li><li>&#x425;&#x43E;&#x43B;&#x43E;&#x434;&#x43D;&#x430;&#x44F; &#x433;&#x43E;&#x43B;&#x43E;&#x432;&#x430; &#x438; &#x437;&#x430;&#x43F;&#x430;&#x441; &#x432;&#x440;&#x435;&#x43C;&#x435;&#x43D;&#x438;</li></ul><p><strong>Cache</strong>. &#x423; &#x43D;&#x430;&#x441; &#x441;&#x432;&#x43E;&#x439; &#x43D;&#x435;&#x431;&#x43E;&#x43B;&#x44C;&#x448;&#x43E;&#x439; CDN &#x438; &#x447;&#x442;&#x43E;&#x431;&#x44B; &#x432;&#x430;&#x43B; &#x437;&#x430;&#x43F;&#x440;&#x43E;&#x441;&#x43E;&#x432; &#x43D;&#x435; &#x43F;&#x43E;&#x43B;&#x43E;&#x436;&#x438;&#x43B; &#x445;&#x440;&#x430;&#x43D;&#x438;&#x43B;&#x438;&#x449;&#x435; &#x441;&#x442;&#x430;&#x442;&#x438;&#x43A;&#x438;, &#x434;&#x43E;&#x431;&#x430;&#x432;&#x438;&#x43B;&#x438; &#x43D;&#x43E;&#x432;&#x44B;&#x439; IP &#x43D;&#x430; &#x431;&#x430;&#x43B;&#x430;&#x43D;&#x441;&#x435;&#x440; &#x441; &#x43C;&#x435;&#x43D;&#x44C;&#x448;&#x438;&#x43C; &#x447;&#x435;&#x43C; &#x443; &#x43E;&#x441;&#x43D;&#x43E;&#x432;&#x43D;&#x44B;&#x445; &#x43C;&#x430;&#x448;&#x438;&#x43D; &#x432;&#x435;&#x441;&#x43E;&#x43C; &#x438; &#x434;&#x430;&#x43B;&#x438; &#x43A;&#x44D;&#x448;&#x443; &#x43F;&#x440;&#x43E;&#x433;&#x440;&#x435;&#x442;&#x44C;&#x441;&#x44F;. &#x41F;&#x43E;&#x441;&#x43B;&#x435; &#x441;&#x442;&#x430;&#x431;&#x438;&#x43B;&#x44C;&#x43D;&#x44B;&#x445; 90% Cache hit, &#x43F;&#x435;&#x440;&#x435;&#x43A;&#x43B;&#x44E;&#x447;&#x430;&#x435;&#x43C; &#x432;&#x435;&#x441;&#x44C; &#x442;&#x440;&#x430;&#x444;&#x438;&#x43A; &#x43D;&#x430; &#x43D;&#x43E;&#x432;&#x44B;&#x435; &#x43C;&#x430;&#x448;&#x438;&#x43D;&#x44B;.</p><figure class="kg-card kg-image-card"><img src="https://igkuz.ru/content/images/2020/04/cache-moving-out-2.png" class="kg-image" alt="&#x41F;&#x435;&#x440;&#x435;&#x435;&#x437;&#x434;" loading="lazy"></figure><p><strong>DB</strong>. Master-Master &#x440;&#x435;&#x43F;&#x43B;&#x438;&#x43A;&#x430;&#x446;&#x438;&#x44F; &#x441; &#x43E;&#x434;&#x43D;&#x438; &#x430;&#x43A;&#x442;&#x438;&#x432;&#x43D;&#x44B;&#x43C; &#x43C;&#x430;&#x441;&#x442;&#x435;&#x440;&#x43E;&#x43C;. &#x418;&#x441;&#x445;&#x43E;&#x434;&#x43D;&#x430;&#x44F; &#x43F;&#x43E;&#x437;&#x438;&#x446;&#x438;&#x44F; old-db0&lt;-&gt;old-db1. &#x41F;&#x440;&#x438;&#x43B;&#x43E;&#x436;&#x435;&#x43D;&#x438;&#x44F; &#x441;&#x43C;&#x43E;&#x442;&#x440;&#x44F;&#x442; HA IP &#x2013;&gt; old-db1.</p><figure class="kg-card kg-image-card"><img src="https://igkuz.ru/content/images/2020/04/moving-out-db1.png" class="kg-image" alt="&#x41F;&#x435;&#x440;&#x435;&#x435;&#x437;&#x434;" loading="lazy"></figure><p>&#x414;&#x435;&#x43B;&#x430;&#x435;&#x43C; read replica new-db1 &#x438; new-db0. &#x41F;&#x440;&#x438;&#x445;&#x43E;&#x434;&#x438;&#x43C; &#x43A; &#x432;&#x438;&#x434;&#x443; newdb0&lt;-new-db1&lt;-old-db1&lt;-&gt;old-db0. &#x42D;&#x442;&#x43E; &#x441;&#x445;&#x435;&#x43C;&#x443; &#x43D;&#x430;&#x434;&#x43E; &#x43D;&#x430;&#x441;&#x442;&#x440;&#x43E;&#x438;&#x442;&#x44C; &#x437;&#x430;&#x440;&#x430;&#x43D;&#x435;&#x435;, &#x447;&#x442;&#x43E;&#x431;&#x44B; &#x440;&#x435;&#x43F;&#x43B;&#x438;&#x43A;&#x438; &#x443;&#x441;&#x43F;&#x435;&#x43B;&#x438; &#x43F;&#x43E;&#x434;&#x442;&#x44F;&#x43D;&#x443;&#x442;&#x44C; &#x434;&#x430;&#x43D;&#x43D;&#x44B;&#x435;.</p><figure class="kg-card kg-image-card"><img src="https://igkuz.ru/content/images/2020/04/moving-out-db2.png" class="kg-image" alt="&#x41F;&#x435;&#x440;&#x435;&#x435;&#x437;&#x434;" loading="lazy"></figure><p>&#x420;&#x432;&#x435;&#x43C; &#x43C;&#x430;&#x441;&#x442;&#x435;&#x440;-&#x43C;&#x430;&#x441;&#x442;&#x435;&#x440; old-db0&lt;-&gt;old-db1, &#x43D;&#x430;&#x441;&#x442;&#x440;&#x430;&#x438;&#x432;&#x430;&#x435;&#x43C; &#x43D;&#x43E;&#x432;&#x44B;&#x439; master-master old-db1&lt;-&gt;new-db1. &#x41F;&#x435;&#x440;&#x435;&#x445;&#x43E;&#x434;&#x438;&#x43C; &#x43A; &#x43F;&#x440;&#x438;&#x43B;&#x43E;&#x436;&#x435;&#x43D;&#x438;&#x44F;&#x43C;.</p><p>&#x41F;&#x43E;&#x434;&#x43D;&#x438;&#x43C;&#x430;&#x435;&#x43C; &#x43F;&#x440;&#x438;&#x43B;&#x43E;&#x436;&#x435;&#x43D;&#x438;&#x44F; &#x43D;&#x430; &#x43D;&#x43E;&#x432;&#x44B;&#x445; &#x43C;&#x430;&#x448;&#x438;&#x43D;&#x430;&#x445;. &#x41D;&#x43E;&#x432;&#x44B;&#x435; &#x438;&#x43D;&#x441;&#x442;&#x430;&#x43D;&#x441;&#x44B; &#x441;&#x43C;&#x43E;&#x442;&#x440;&#x44F;&#x442; &#x432; HA IP &#x2013;&gt; new-db1. &#x41E;&#x447;&#x435;&#x440;&#x435;&#x434;&#x438; &#x43D;&#x435; &#x43F;&#x43E;&#x434;&#x43D;&#x438;&#x43C;&#x430;&#x435;&#x43C;, &#x437;&#x430;&#x43F;&#x438;&#x441;&#x438; &#x432; &#x431;&#x430;&#x437;&#x443; &#x43F;&#x43E;&#x43A;&#x430; &#x43D;&#x435;&#x442;. &#x41F;&#x440;&#x43E;&#x432;&#x435;&#x440;&#x44F;&#x435;&#x43C; &#x440;&#x430;&#x431;&#x43E;&#x442;&#x43E;&#x441;&#x43F;&#x43E;&#x441;&#x43E;&#x431;&#x43D;&#x43E;&#x441;&#x442;&#x44C;. &#x41F;&#x440;&#x43E;&#x433;&#x440;&#x435;&#x432;&#x430;&#x435;&#x43C; &#x43A;&#x44D;&#x448; &#x43D;&#x435;&#x441;&#x43A;&#x43E;&#x43B;&#x44C;&#x43A;&#x438;&#x43C;&#x438; &#x437;&#x430;&#x43F;&#x440;&#x43E;&#x441;&#x430;&#x43C;&#x438;.</p><figure class="kg-card kg-image-card"><img src="https://igkuz.ru/content/images/2020/04/moving-out-db3.png" class="kg-image" alt="&#x41F;&#x435;&#x440;&#x435;&#x435;&#x437;&#x434;" loading="lazy"></figure><p>&#x41D;&#x430; &#x441;&#x442;&#x430;&#x440;&#x44B;&#x445; &#x43C;&#x430;&#x448;&#x438;&#x43D;&#x430;&#x445; &#x432;&#x44B;&#x43A;&#x43B;&#x44E;&#x447;&#x430;&#x435;&#x43C; &#x43E;&#x447;&#x435;&#x440;&#x435;&#x434;&#x438; &#x438; &#x432;&#x441;&#x451; &#x447;&#x442;&#x43E; &#x43C;&#x43E;&#x436;&#x435;&#x442; &#x43F;&#x438;&#x441;&#x430;&#x442;&#x44C; &#x432; &#x431;&#x430;&#x437;&#x443;, &#x43A;&#x440;&#x43E;&#x43C;&#x435; &#x43F;&#x43E;&#x43B;&#x44C;&#x437;&#x43E;&#x432;&#x430;&#x442;&#x435;&#x43B;&#x44C;&#x441;&#x43A;&#x438;&#x445; &#x437;&#x430;&#x43F;&#x440;&#x43E;&#x441;&#x43E;&#x432;. &#x414;&#x435;&#x43B;&#x430;&#x435;&#x43C; &#x43F;&#x440;&#x43E;&#x43A;&#x441;&#x438;&#x440;&#x43E;&#x432;&#x430;&#x43D;&#x438;&#x435; &#x437;&#x430;&#x43F;&#x440;&#x43E;&#x441;&#x43E;&#x432; &#x432; &#x43D;&#x43E;&#x432;&#x44B;&#x439; DC &#x43D;&#x430; nginx. &#x41F;&#x435;&#x440;&#x435;&#x43A;&#x43B;&#x44E;&#x447;&#x430;&#x435;&#x43C; DNS. &#x423;&#x441;&#x43A;&#x43E;&#x440;&#x44F;&#x435;&#x43C; &#x43E;&#x431;&#x43D;&#x43E;&#x432;&#x43B;&#x435;&#x43D;&#x438;&#x435; &#x43F;&#x443;&#x431;&#x43B;&#x438;&#x447;&#x43D;&#x44B;&#x445; DNS &#x447;&#x435;&#x440;&#x435;&#x437; &#x432;&#x43E;&#x43B;&#x448;&#x435;&#x431;&#x43D;&#x443;&#x44E; <a href="https://developers.google.com/speed/public-dns/cache?ref=igkuz.ru" rel="noopener nofollow">&#x43A;&#x43D;&#x43E;&#x43F;&#x43A;&#x443; Google</a>.</p><p>&#x412;&#x44B;&#x43A;&#x43B;&#x44E;&#x447;&#x430;&#x435;&#x43C; &#x43F;&#x440;&#x438;&#x43B;&#x43E;&#x436;&#x435;&#x43D;&#x438;&#x44F; &#x43D;&#x430; &#x441;&#x442;&#x430;&#x440;&#x44B;&#x445; &#x43C;&#x430;&#x448;&#x438;&#x43D;&#x430;&#x445;, &#x43F;&#x440;&#x43E;&#x432;&#x435;&#x440;&#x44F;&#x435;&#x43C; &#x43D;&#x430;&#x43B;&#x438;&#x447;&#x438;&#x435; &#x43A;&#x43E;&#x43D;&#x43D;&#x435;&#x43A;&#x442;&#x43E;&#x432; &#x43D;&#x430; old-db1. &#x41A;&#x43E;&#x433;&#x434;&#x430; &#x43A;&#x440;&#x43E;&#x43C;&#x435; &#x43F;&#x440;&#x43E;&#x446;&#x435;&#x441;&#x441;&#x43E;&#x432; &#x440;&#x435;&#x43F;&#x43B;&#x438;&#x43A;&#x430;&#x446;&#x438;&#x438; &#x43D;&#x438;&#x447;&#x435;&#x433;&#x43E; &#x43D;&#x435;&#x442;, &#x438;&#x434;&#x435;&#x43C; &#x440;&#x432;&#x430;&#x442;&#x44C; &#x43C;&#x430;&#x441;&#x442;&#x435;&#x440;-&#x43C;&#x430;&#x441;&#x442;&#x435;&#x440;. &#x414;&#x435;&#x43B;&#x430;&#x435;&#x43C; &#x43D;&#x43E;&#x432;&#x44B;&#x439; &#x43C;&#x430;&#x441;&#x442;&#x435;&#x440;-&#x43C;&#x430;&#x441;&#x442;&#x435;&#x440; new-db1&lt;&#x2013;&gt;new-db0. &#x420;&#x432;&#x435;&#x43C; &#x441;&#x432;&#x44F;&#x437;&#x44C; &#x441;&#x43E; &#x441;&#x442;&#x430;&#x440;&#x43E;&#x439; &#x431;&#x430;&#x437;&#x43E;&#x439; &#x432; DC1.</p><p>&#x412;&#x43A;&#x43B;&#x44E;&#x447;&#x430;&#x435;&#x43C; &#x43E;&#x447;&#x435;&#x440;&#x435;&#x434;&#x438; &#x438; &#x434;&#x43E;&#x43F;&#x43E;&#x43B;&#x43D;&#x438;&#x442;&#x435;&#x43B;&#x44C;&#x43D;&#x44B;&#x435; &#x441;&#x435;&#x440;&#x432;&#x438;&#x441;&#x44B;. &#x417;&#x430;&#x43F;&#x443;&#x441;&#x43A;&#x430;&#x435;&#x43C; &#x43F;&#x435;&#x440;&#x435;&#x438;&#x43D;&#x434;&#x435;&#x43A;&#x441;&#x430;&#x446;&#x438;&#x44E; &#x434;&#x43E;&#x43A;&#x443;&#x43C;&#x435;&#x43D;&#x442;&#x43E;&#x432; &#x432; Elastic. &#x41C;&#x43E;&#x436;&#x43D;&#x43E; &#x431;&#x44B;&#x43B;&#x43E; &#x431;&#x44B; &#x43F;&#x435;&#x440;&#x435;&#x442;&#x430;&#x449;&#x438;&#x442;&#x44C; &#x431;&#x430;&#x437;&#x443; &#x438; &#x434;&#x43E;&#x438;&#x43D;&#x434;&#x435;&#x43A;&#x441;&#x438;&#x440;&#x43E;&#x432;&#x430;&#x442;&#x44C;, &#x43D;&#x43E; &#x434;&#x430;&#x43D;&#x43D;&#x44B;&#x445; &#x43D;&#x435;&#x43C;&#x43D;&#x43E;&#x433;&#x43E;, &#x43F;&#x43E;&#x44D;&#x442;&#x43E;&#x43C;&#x443; &#x440;&#x435;&#x448;&#x438;&#x43B;&#x438; &#x441;&#x434;&#x435;&#x43B;&#x430;&#x442;&#x44C; &#x43F;&#x435;&#x440;&#x435;&#x438;&#x43D;&#x434;&#x435;&#x43A;&#x441; &#x434;&#x43B;&#x44F; &#x43F;&#x440;&#x43E;&#x444;&#x438;&#x43B;&#x430;&#x43A;&#x442;&#x438;&#x43A;&#x438;. Elastic &#x442;&#x43E;&#x43B;&#x44C;&#x43A;&#x43E; &#x434;&#x43B;&#x44F; &#x43F;&#x43E;&#x438;&#x441;&#x43A;&#x430;, &#x430; &#x43E;&#x43D; &#x438;&#x441;&#x442;&#x43E;&#x440;&#x438;&#x447;&#x435;&#x441;&#x43A;&#x438; &#x434;&#x435;&#x43B;&#x430;&#x435;&#x442; &lt;1% &#x442;&#x440;&#x430;&#x444;&#x438;&#x43A;&#x430;, &#x43F;&#x43E;&#x44D;&#x442;&#x43E;&#x43C;&#x443; &#x43D;&#x435; &#x441;&#x442;&#x440;&#x430;&#x448;&#x43D;&#x43E; &#x432;&#x44B;&#x434;&#x430;&#x442;&#x44C; &#x43F;&#x43E;&#x43B;&#x44C;&#x437;&#x43E;&#x432;&#x435;&#x442;&#x43B;&#x44F;&#x43C; &#x43F;&#x443;&#x441;&#x442;&#x43E;&#x439; &#x43E;&#x442;&#x432;&#x435;&#x442;.</p><p>&#x414;&#x435;&#x43B;&#x430;&#x435;&#x43C; &#x440;&#x443;&#x447;&#x43D;&#x44B;&#x435; &#x43F;&#x440;&#x43E;&#x432;&#x435;&#x440;&#x43A;&#x438; &#x43A;&#x440;&#x438;&#x442;&#x438;&#x447;&#x43D;&#x44B;&#x445; &#x43C;&#x435;&#x441;&#x442; &#x43F;&#x440;&#x438;&#x43B;&#x43E;&#x436;&#x435;&#x43D;&#x438;&#x439;. &#x415;&#x441;&#x43B;&#x438; &#x447;&#x442;&#x43E;-&#x442;&#x43E; &#x438;&#x434;&#x435;&#x442; &#x43D;&#x435; &#x442;&#x430;&#x43A;, &#x442;&#x43E; &#x447;&#x438;&#x43D;&#x438;&#x43C;, &#x43D;&#x43E; &#x443; &#x43D;&#x430;&#x441; &#x431;&#x44B;&#x43B;&#x43E; &#x43E;&#x43A;.</p><p>&#x423; &#x438;&#x437;&#x434;&#x430;&#x43D;&#x438;&#x439; &#x431;&#x44B;&#x43B;&#x430; &#x43A;&#x443;&#x447;&#x430; &#x434;&#x43E;&#x43F;&#x43E;&#x43B;&#x43D;&#x438;&#x442;&#x435;&#x43B;&#x44C;&#x43D;&#x44B;&#x445; &#x434;&#x43E;&#x43C;&#x435;&#x43D;&#x43E;&#x432;, &#x43D;&#x443;&#x436;&#x43D;&#x43E; &#x43F;&#x435;&#x440;&#x435;&#x43A;&#x43B;&#x44E;&#x447;&#x438;&#x442;&#x44C; &#x432;&#x441;&#x435;. &#x427;&#x442;&#x43E; &#x438;&#x43C;&#x435;&#x43D;&#x43D;&#x43E; &#x43C;&#x43E;&#x436;&#x43D;&#x43E; &#x43D;&#x430;&#x439;&#x442;&#x438; &#x432; &#x43A;&#x43E;&#x43D;&#x444;&#x438;&#x433;&#x430;&#x445; nginx &#x432; &#x440;&#x430;&#x437;&#x434;&#x435;&#x43B;&#x435; server &#x2013;&gt; server_name.</p><p>&#x41F;&#x440;&#x43E;&#x432;&#x435;&#x440;&#x44F;&#x435;&#x43C; &#x432;&#x441;&#x435; &#x43F;&#x440;&#x430;&#x432;&#x438;&#x43B;&#x430; &#x430;&#x43B;&#x435;&#x440;&#x442;&#x43E;&#x432; &#x43C;&#x43E;&#x43D;&#x438;&#x442;&#x43E;&#x440;&#x438;&#x43D;&#x433;&#x430; &#x438; &#x438;&#x434;&#x435;&#x43C; &#x43E;&#x442;&#x434;&#x44B;&#x445;&#x430;&#x442;&#x44C;.</p><p>&#x421;&#x43F;&#x443;&#x441;&#x442;&#x44F; 2 &#x434;&#x43D;&#x44F;, &#x43A;&#x43E;&#x433;&#x434;&#x430; DNS &#x43E;&#x431;&#x43D;&#x43E;&#x432;&#x438;&#x43B;&#x438;&#x441;&#x44C;, &#x43D;&#x430;&#x447;&#x438;&#x43D;&#x430;&#x435;&#x43C; &#x442;&#x443;&#x448;&#x438;&#x442;&#x44C; &#x43C;&#x430;&#x448;&#x438;&#x43D;&#x44B; &#x432; &#x441;&#x442;&#x430;&#x440;&#x43E;&#x43C; &#x414;&#x426; &#x438; &#x437;&#x430;&#x43F;&#x440;&#x430;&#x448;&#x438;&#x432;&#x430;&#x435;&#x43C; &#x438;&#x445; &#x432;&#x44B;&#x43A;&#x43B;&#x44E;&#x447;&#x435;&#x43D;&#x438;&#x435;.</p><p>&#x412; &#x438;&#x442;&#x43E;&#x433;&#x435; &#x43C;&#x44B; &#x43F;&#x43E;&#x43B;&#x443;&#x447;&#x438;&#x43B;&#x438; &#x441;&#x43D;&#x438;&#x436;&#x435;&#x43D;&#x438;&#x435; &#x441;&#x442;&#x43E;&#x438;&#x43C;&#x43E;&#x441;&#x442;&#x438; &#x432;&#x43B;&#x430;&#x434;&#x435;&#x43D;&#x438;&#x44F; &#x432; 4 &#x440;&#x430;&#x437;&#x430;, &#x43D;&#x43E; &#x43F;&#x43E;&#x442;&#x435;&#x440;&#x44F;&#x43B;&#x438; &#x432; &#x43A;&#x43E;&#x43B;-&#x432;&#x435; &#x43F;&#x440;&#x43E;&#x446;&#x435;&#x441;&#x441;&#x43E;&#x440;&#x43E;&#x432;.</p>]]></content:encoded></item><item><title><![CDATA[Отражая DDoS]]></title><description><![CDATA[Представьте ситуацию - вы идете домой с работы по знакомой улице, слушаете музыку и готовитесь достать ключи, но из-за угла выходит пара…]]></description><link>https://igkuz.ru/otrazhaia-ddos/</link><guid isPermaLink="false">5e9209026d9007355d8bde86</guid><category><![CDATA[DDoS protection]]></category><category><![CDATA[System Administration]]></category><category><![CDATA[RabbitMQ]]></category><category><![CDATA[Cybersecurity]]></category><dc:creator><![CDATA[Igor Kuznetsov]]></dc:creator><pubDate>Thu, 04 Jan 2018 07:00:00 GMT</pubDate><content:encoded><![CDATA[<p>&#x41F;&#x440;&#x435;&#x434;&#x441;&#x442;&#x430;&#x432;&#x44C;&#x442;&#x435; &#x441;&#x438;&#x442;&#x443;&#x430;&#x446;&#x438;&#x44E; &#x2014; &#x432;&#x44B; &#x438;&#x434;&#x435;&#x442;&#x435; &#x434;&#x43E;&#x43C;&#x43E;&#x439; &#x441; &#x440;&#x430;&#x431;&#x43E;&#x442;&#x44B; &#x43F;&#x43E; &#x437;&#x43D;&#x430;&#x43A;&#x43E;&#x43C;&#x43E;&#x439; &#x443;&#x43B;&#x438;&#x446;&#x435;, &#x441;&#x43B;&#x443;&#x448;&#x430;&#x435;&#x442;&#x435; &#x43C;&#x443;&#x437;&#x44B;&#x43A;&#x443; &#x438; &#x433;&#x43E;&#x442;&#x43E;&#x432;&#x438;&#x442;&#x435;&#x441;&#x44C; &#x434;&#x43E;&#x441;&#x442;&#x430;&#x442;&#x44C; &#x43A;&#x43B;&#x44E;&#x447;&#x438;, &#x43D;&#x43E; &#x438;&#x437;-&#x437;&#x430; &#x443;&#x433;&#x43B;&#x430; &#x432;&#x44B;&#x445;&#x43E;&#x434;&#x438;&#x442; &#x43F;&#x430;&#x440;&#x430; &#x437;&#x434;&#x43E;&#x440;&#x43E;&#x432;&#x44B;&#x445; &#x440;&#x435;&#x431;&#x44F;&#x442;, &#x43A;&#x43E;&#x442;&#x43E;&#x440;&#x44B;&#x435; &#x432;&#x44B;&#x448;&#x435;, &#x441;&#x438;&#x43B;&#x44C;&#x43D;&#x435;&#x435;, &#x431;&#x44B;&#x441;&#x442;&#x440;&#x435;&#x435; (&#x43D;&#x430; &#x43F;&#x435;&#x440;&#x432;&#x44B;&#x439; &#x432;&#x437;&#x433;&#x43B;&#x44F;&#x434;) &#x438; &#x431;&#x44C;&#x44E;&#x442; &#x432;&#x430;&#x441; &#x43F;&#x440;&#x44F;&#x43C;&#x44B;&#x43C; &#x432; &#x447;&#x435;&#x43B;&#x44E;&#x441;&#x442;&#x44C;. &#x412;&#x43E;&#x442; &#x442;&#x430;&#x43A; &#x432;&#x44B;&#x433;&#x43B;&#x44F;&#x434;&#x438;&#x442; DDoS &#x430;&#x442;&#x430;&#x43A;&#x430; &#x434;&#x43B;&#x44F; 99% &#x43A;&#x43E;&#x43C;&#x43F;&#x430;&#x43D;&#x438;&#x439;. &#x42D;&#x442;&#x43E; &#x43D;&#x435;&#x43E;&#x436;&#x438;&#x434;&#x430;&#x43D;&#x43D;&#x43E; &#x438; &#x43D;&#x435;&#x43F;&#x440;&#x438;&#x44F;&#x442;&#x43D;&#x43E; &#x434;&#x43B;&#x44F; &#x432;&#x43B;&#x430;&#x434;&#x435;&#x43B;&#x44C;&#x446;&#x430; &#x431;&#x438;&#x437;&#x43D;&#x435;&#x441;&#x430;, &#x43D;&#x43E; &#x43E;&#x447;&#x435;&#x43D;&#x44C; &#x438;&#x43D;&#x442;&#x435;&#x440;&#x435;&#x441;&#x43D;&#x43E; &#x434;&#x43B;&#x44F; &#x440;&#x430;&#x437;&#x440;&#x430;&#x431;&#x43E;&#x442;&#x447;&#x438;&#x43A;&#x43E;&#x432; &#x438; &#x441;&#x438;&#x441;&#x442;&#x435;&#x43C;&#x43D;&#x44B;&#x445; &#x430;&#x434;&#x43C;&#x438;&#x43D;&#x438;&#x441;&#x442;&#x440;&#x430;&#x442;&#x43E;&#x440;&#x43E;&#x432;.</p><p>&#x41E;&#x442;&#x43B;&#x438;&#x447;&#x43D;&#x430;&#x44F; &#x432;&#x43E;&#x437;&#x43C;&#x43E;&#x436;&#x43D;&#x43E;&#x441;&#x442;&#x44C; &#x43F;&#x440;&#x43E;&#x432;&#x435;&#x440;&#x438;&#x442;&#x44C; &#x440;&#x435;&#x430;&#x43A;&#x446;&#x438;&#x44E;: &#x445;&#x432;&#x430;&#x43B;&#x435;&#x43D;&#x44B;&#x435; &#x441;&#x438;&#x441;&#x442;&#x435;&#x43C;&#x44B; &#x43C;&#x43E;&#x43D;&#x438;&#x442;&#x43E;&#x440;&#x438;&#x43D;&#x433;&#x430;, &#x43E;&#x431;&#x435;&#x449;&#x430;&#x43D;&#x43D;&#x44B;&#x435; &#x43F;&#x43B;&#x44E;&#x448;&#x43A;&#x438; &#x43E;&#x442; &#x441;&#x43E;&#x444;&#x442;&#x430; &#x438; &#x43F;&#x440;&#x43E;&#x432;&#x430;&#x439;&#x434;&#x435;&#x440;&#x43E;&#x432;, &#x438;, &#x441;&#x430;&#x43C;&#x43E;&#x435; &#x433;&#x43B;&#x430;&#x432;&#x43D;&#x43E;&#x435;, &#x441;&#x43E;&#x431;&#x441;&#x442;&#x432;&#x435;&#x43D;&#x43D;&#x44B;&#x435; &#x440;&#x435;&#x448;&#x435;&#x43D;&#x438;&#x44F; &#x43F;&#x43E; &#x440;&#x435;&#x437;&#x435;&#x440;&#x432;&#x438;&#x440;&#x43E;&#x432;&#x430;&#x43D;&#x438;&#x44E;.</p><p>&#x417;&#x430; &#x43F;&#x43E;&#x441;&#x43B;&#x435;&#x434;&#x43D;&#x438;&#x435; 4 &#x43C;&#x435;&#x441;&#x44F;&#x446;&#x430; &#x43D;&#x430;&#x43F;&#x430;&#x43B;&#x438; &#x43D;&#x430; 2 &#x43D;&#x430;&#x448;&#x438;&#x445; &#x438;&#x437;&#x434;&#x430;&#x43D;&#x438;&#x44F;. &#x412; &#x43F;&#x435;&#x440;&#x432;&#x44B;&#x439; &#x440;&#x430;&#x437; &#x432;&#x44B;&#x43C;&#x43E;&#x433;&#x430;&#x43B;&#x438; 1 BTC, &#x432;&#x442;&#x43E;&#x440;&#x43E;&#x439; &#x440;&#x430;&#x437; &#x43D;&#x438;&#x447;&#x435;&#x433;&#x43E; &#x43D;&#x435; &#x43F;&#x440;&#x43E;&#x441;&#x438;&#x43B;&#x438;, &#x43F;&#x440;&#x43E;&#x441;&#x442;&#x43E; &#x431;&#x438;&#x43B;&#x438;.</p><p>DDoS &#x430;&#x442;&#x430;&#x43A;&#x430; &#x44D;&#x442;&#x43E; &#x432;&#x43D;&#x435;&#x448;&#x442;&#x430;&#x442;&#x43D;&#x430;&#x44F; &#x441;&#x438;&#x442;&#x443;&#x430;&#x446;&#x438;&#x44F; &#x438; &#x437;&#x430;&#x43A;&#x43B;&#x430;&#x434;&#x44B;&#x432;&#x430;&#x442;&#x44C;&#x441;&#x44F; &#x43F;&#x43E;&#x434; 2000% &#x43D;&#x430;&#x433;&#x440;&#x443;&#x437;&#x43A;&#x438; &#x43F;&#x440;&#x438; &#x43F;&#x43E;&#x441;&#x442;&#x440;&#x43E;&#x435;&#x43D;&#x438;&#x438; &#x438;&#x43D;&#x444;&#x440;&#x430;&#x441;&#x442;&#x440;&#x443;&#x43A;&#x442;&#x443;&#x440;&#x44B; &#x43D;&#x435;&#x442; &#x441;&#x43C;&#x44B;&#x441;&#x43B;&#x430;.</p><p>&#x41F;&#x43E;&#x447;&#x435;&#x43C;&#x443;? &#x2014; &#x41F;&#x43E;&#x442;&#x43E;&#x43C;&#x443; &#x447;&#x442;&#x43E; &#x430;&#x442;&#x430;&#x43A;&#x430; &#x43C;&#x43E;&#x436;&#x435;&#x442; &#x431;&#x44B;&#x442;&#x44C; &#x442;&#x430;&#x43A;&#x43E;&#x439;, &#x447;&#x442;&#x43E; Akamai &#x438; Yandex &#x43D;&#x435; &#x43E;&#x442;&#x43E;&#x431;&#x44C;&#x44E;&#x442;&#x441;&#x44F;. &#x418; &#x432;&#x43E;&#x437;&#x43C;&#x43E;&#x436;&#x43D;&#x43E;&#x441;&#x442;&#x44C; &#x434;&#x435;&#x440;&#x436;&#x430;&#x442;&#x44C; 2000% &#x431;&#x443;&#x434;&#x435;&#x442; &#x43A;&#x430;&#x43F;&#x43B;&#x435;&#x439; &#x432; &#x43C;&#x43E;&#x440;&#x435;, &#x43D;&#x43E; &#x437;&#x430; &#x432;&#x440;&#x435;&#x43C;&#x44F; &#x43F;&#x440;&#x43E;&#x441;&#x442;&#x43E;&#x44F; &#x43E;&#x431;&#x43E;&#x440;&#x443;&#x434;&#x43E;&#x432;&#x430;&#x43D;&#x438;&#x44F; &#x43A;&#x43E;&#x43C;&#x43F;&#x430;&#x43D;&#x438;&#x44F; &#x441;&#x43E;&#x436;&#x436;&#x435;&#x442; &#x432;&#x430;&#x433;&#x43E;&#x43D; &#x434;&#x435;&#x43D;&#x435;&#x433;, &#x438; &#x432;&#x441;&#x435; &#x440;&#x430;&#x432;&#x43D;&#x43E; &#x440;&#x435;&#x441;&#x443;&#x440;&#x441; &#x43B;&#x44F;&#x436;&#x435;&#x442;.</p><p>&#x41D;&#x443;&#x436;&#x43D;&#x43E; &#x43B;&#x438; &#x433;&#x43E;&#x442;&#x43E;&#x432;&#x438;&#x442;&#x44C;&#x441;&#x44F;, &#x435;&#x441;&#x43B;&#x438; &#x432;&#x441;&#x435; &#x442;&#x430;&#x43A; &#x43F;&#x43B;&#x43E;&#x445;&#x43E;? &#x2014; &#x41E;&#x434;&#x43D;&#x43E;&#x437;&#x43D;&#x430;&#x447;&#x43D;&#x43E;. &#x41D;&#x43E; &#x43A;&#x430;&#x43A; &#x43E;&#x431;&#x44B;&#x447;&#x43D;&#x43E; &#x441; &#x443;&#x43C;&#x43E;&#x43C;.</p><h2 id="-">&#x41A;&#x430;&#x43A; &#x44D;&#x442;&#x43E; &#x432;&#x44B;&#x433;&#x43B;&#x44F;&#x434;&#x438;&#x442; &#x432; &#x43A;&#x438;&#x43D;&#x43E;?</h2><figure class="kg-card kg-embed-card"><iframe width="459" height="344" src="https://www.youtube.com/embed/8FdvWuSl7eY?feature=oembed" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe></figure><p>&#x41A;&#x443;&#x447;&#x430; &#x43E;&#x442;&#x43A;&#x440;&#x44B;&#x442;&#x44B;&#x445; &#x442;&#x435;&#x440;&#x43C;&#x438;&#x43D;&#x430;&#x43B;&#x43E;&#x432;, &#x447;&#x442;&#x43E;-&#x442;&#x43E; &#x43A;&#x443;&#x434;&#x430;-&#x442;&#x43E; &#x43B;&#x435;&#x442;&#x438;&#x442;, &#x448;&#x438;&#x444;&#x440;&#x443;&#x435;&#x442;&#x441;&#x44F;-&#x43A;&#x440;&#x438;&#x43F;&#x442;&#x443;&#x435;&#x442;&#x441;&#x44F;-&#x43F;&#x438;&#x43D;&#x433;&#x443;&#x435;&#x442;&#x441;&#x44F;.</p><p>[&#x417;&#x430;&#x433;&#x43E;&#x440;&#x430;&#x435;&#x442;&#x441;&#x44F; &#x43A;&#x440;&#x430;&#x441;&#x43D;&#x430;&#x44F; &#x43B;&#x430;&#x43C;&#x43F;&#x43E;&#x447;&#x43A;&#x430;].</p><p>&#x2014; &#x421;&#x44D;&#x440;, &#x43D;&#x430; &#x43D;&#x430;&#x441; &#x43D;&#x430;&#x43F;&#x430;&#x43B;&#x438;</p><p>&#x2013;&#x2013; &#x41F;&#x43E;&#x43A;&#x430;&#x436;&#x438; &#x438;&#x43C;, &#x414;&#x436;&#x43E;&#x43D;.</p><p>[&#x422;&#x443;&#x442; &#x43E;&#x431;&#x44F;&#x437;&#x430;&#x442;&#x435;&#x43B;&#x44C;&#x43D;&#x43E; &#x43B;&#x43E;&#x43C;&#x430;&#x435;&#x442;&#x441;&#x44F; &#x441;&#x43F;&#x443;&#x442;&#x43D;&#x438;&#x43A;, &#x434;&#x435;&#x442;&#x435;&#x43A;&#x442;&#x438;&#x442;&#x441;&#x44F; &#x43F;&#x43B;&#x43E;&#x445;&#x43E;&#x439; &#x43F;&#x430;&#x440;&#x435;&#x43D;&#x44C; &#x438; &#x432;&#x43E;&#x442; &#x443;&#x436;&#x435; &#x431;&#x440;&#x430;&#x432;&#x44B;&#x435; &#x440;&#x435;&#x431;&#x44F;&#x442;&#x430; &#x432;&#x44B;&#x43D;&#x43E;&#x441;&#x44F;&#x442; &#x434;&#x432;&#x435;&#x440;&#x44C; &#x43A;&#x430;&#x43A;&#x43E;&#x433;&#x43E;-&#x43D;&#x438;&#x431;&#x443;&#x434;&#x44C; &#x431;&#x443;&#x43D;&#x43A;&#x435;&#x440;&#x430; &#x438; &#x432;&#x441;&#x435;&#x445; &#x43B;&#x430;&#x441;&#x442;&#x430;&#x44E;&#x442;].</p><h4 id="--1">&#x41A;&#x430;&#x43A; &#x44D;&#x442;&#x43E; &#x432;&#x44B;&#x433;&#x43B;&#x44F;&#x434;&#x438;&#x442; &#x432; &#x440;&#x435;&#x430;&#x43B;&#x44C;&#x43D;&#x43E;&#x441;&#x442;&#x438;?</h4><p>&#x415;&#x434;&#x435;&#x448;&#x44C; &#x43D;&#x43E;&#x447;&#x44C;&#x44E; &#x438;&#x437; &#x431;&#x430;&#x440;&#x430; &#x43D;&#x430; &#x442;&#x430;&#x43A;&#x441;&#x438;. &#x417;&#x432;&#x43E;&#x43D;&#x438;&#x442; &#x43C;&#x43E;&#x43D;&#x438;&#x442;&#x43E;&#x440;&#x438;&#x43D;&#x433; &#x438; &#x44D;&#x43B;&#x435;&#x43A;&#x442;&#x440;&#x43E;&#x43D;&#x43D;&#x44B;&#x439; &#x433;&#x43E;&#x43B;&#x43E;&#x441; &#x43D;&#x430;&#x434;&#x438;&#x43A;&#x442;&#x43E;&#x432;&#x44B;&#x432;&#x430;&#x435;&#x442; &#x441;&#x43E;&#x43E;&#x431;&#x449;&#x435;&#x43D;&#x438;&#x435;&#x200A;&#x2014;&#x200A;&lt;sitename&gt; unreachable. &#x421; &#x442;&#x435;&#x43B;&#x435;&#x444;&#x43E;&#x43D;&#x430; 504 &#x438; &#x441;&#x43F;&#x438;&#x43D;&#x43D;&#x435;&#x440; &#x431;&#x440;&#x430;&#x443;&#x437;&#x435;&#x440;&#x430; &#x43D;&#x430;&#x440;&#x435;&#x437;&#x430;&#x435;&#x442; &#x431;&#x435;&#x441;&#x43A;&#x43E;&#x43D;&#x435;&#x447;&#x43D;&#x44B;&#x435; &#x43A;&#x440;&#x443;&#x433;&#x438; &#x43F;&#x43E;&#x43A;&#x430; &#x442;&#x44B; &#x441;&#x443;&#x434;&#x43E;&#x440;&#x43E;&#x436;&#x43D;&#x43E; &#x43F;&#x44B;&#x442;&#x430;&#x435;&#x448;&#x44C;&#x441;&#x44F; &#x432;&#x441;&#x43F;&#x43E;&#x43C;&#x43D;&#x438;&#x442;&#x44C; &#x43F;&#x430;&#x440;&#x43E;&#x43B;&#x44C; &#x43E;&#x442; Zabbix&#x2026; &#x410; &#x442;&#x430;&#x43C; &#x43B;&#x430;&#x432;&#x438;&#x43D;&#x430; 500-&#x445; &#x438; &#x432; 1000 &#x440;&#x430;&#x437; &#x431;&#x43E;&#x43B;&#x44C;&#x448;&#x435; &#x437;&#x430;&#x43F;&#x440;&#x43E;&#x441;&#x43E;&#x432;. &#x418; &#x442;&#x435;&#x431;&#x435; &#x43D;&#x430;&#x434;&#x43E; &#x447;&#x442;&#x43E;-&#x442;&#x43E; &#x434;&#x435;&#x43B;&#x430;&#x442;&#x44C;. &#x412;&#x441;&#x435; &#x441;&#x43F;&#x443;&#x442;&#x43D;&#x438;&#x43A;&#x438; &#x434;&#x43E; &#x442;&#x435;&#x431;&#x44F; &#x443;&#x436;&#x435; &#x441;&#x43B;&#x43E;&#x43C;&#x430;&#x43B;&#x438; &#x43F;&#x440;&#x438; &#x437;&#x430;&#x43F;&#x443;&#x441;&#x43A;&#x435; &#x438;&#x43B;&#x438; &#x43F;&#x440;&#x438; &#x441;&#x431;&#x43E;&#x440;&#x43A;&#x435;, &#x442;&#x430;&#x43A; &#x447;&#x442;&#x43E; &#x432;&#x44B;&#x431;&#x43E;&#x440; &#x43D;&#x435;&#x432;&#x435;&#x43B;&#x438;&#x43A;, &#x43D;&#x430;&#x434;&#x43E; &#x43A;&#x430;&#x43A;-&#x442;&#x43E; &#x43E;&#x442;&#x431;&#x438;&#x432;&#x430;&#x442;&#x44C;&#x441;&#x44F;. &#x41A;&#x430;&#x43A; &#x432; &#x43A;&#x438;&#x43D;&#x43E; &#x431;&#x44B;&#x432;&#x430;&#x435;&#x442; &#x442;&#x43E;&#x43B;&#x44C;&#x43A;&#x43E; &#x432; &#x43A;&#x438;&#x43D;&#x43E;.</p><figure class="kg-card kg-image-card kg-width-wide kg-card-hascaption"><img src="https://igkuz.ru/content/images/2020/04/zabbix-ddos.png" class="kg-image" alt loading="lazy"><figcaption>&#x421;&#x43A;&#x440;&#x438;&#x43D; Zabbix &#x441; &#x43E;&#x434;&#x43D;&#x43E;&#x439; &#x438;&#x437; app &#x43C;&#x430;&#x448;&#x438;&#x43D;. 500&#x200A;&#x2014;&#x200A;&#x447;&#x435;&#x440;&#x43D;&#x44B;&#x439;, 400&#x200A;&#x2014;&#x200A;&#x43A;&#x440;&#x430;&#x441;&#x43D;&#x44B;&#x439;, total&#x200A;&#x2014;&#x200A;&#x437;&#x435;&#x43B;&#x435;&#x43D;&#x44B;&#x439;.</figcaption></figure><p>&#x41D;&#x43E;&#x440;&#x43C;&#x430;&#x43B;&#x44C;&#x43D;&#x430;&#x44F; &#x43D;&#x430;&#x433;&#x440;&#x443;&#x437;&#x43A;&#x430; &#x432; &#x44D;&#x442;&#x43E; &#x432;&#x440;&#x435;&#x43C;&#x44F; 600&#x2013;800rpm &#x43D;&#x430; 1 app &#x43C;&#x430;&#x448;&#x438;&#x43D;&#x443;.</p><h4 id="--2">&#x41A;&#x430;&#x43A; &#x438;&#x434;&#x435;&#x442; &#x430;&#x442;&#x430;&#x43A;&#x430;?</h4><p>&#x41D;&#x430;&#x441; &#x430;&#x442;&#x430;&#x43A;&#x43E;&#x432;&#x430;&#x43B;&#x438; &#x434;&#x432;&#x443;&#x43C;&#x44F; &#x441;&#x430;&#x43C;&#x44B;&#x43C;&#x438; &#x43F;&#x440;&#x43E;&#x441;&#x442;&#x44B;&#x43C;&#x438; &#x438; &#x434;&#x435;&#x439;&#x441;&#x442;&#x432;&#x435;&#x43D;&#x43D;&#x44B;&#x43C;&#x438; &#x441;&#x43F;&#x43E;&#x441;&#x43E;&#x431;&#x430;&#x43C;&#x438;:</p><ol><li>&#x410;&#x442;&#x430;&#x43A;&#x430; &#x43D;&#x430; &#x443;&#x440;&#x43E;&#x432;&#x43D;&#x435; <a href="https://en.wikipedia.org/wiki/Application_layer?ref=igkuz.ru" rel="noopener">&#x43F;&#x440;&#x438;&#x43B;&#x43E;&#x436;&#x435;&#x43D;&#x438;&#x44F;</a> (L7). GET/POST &#x437;&#x430;&#x43F;&#x440;&#x43E;&#x441;&#x44B; &#x432; &#x440;&#x430;&#x437;&#x43D;&#x44B;&#x435; location (/, /login, /wp-login) &#x441; &#x440;&#x430;&#x43D;&#x434;&#x43E;&#x43C;&#x438;&#x437;&#x430;&#x446;&#x438;&#x435;&#x439; User-Agent &#x438; cookie.</li><li>&#x410;&#x442;&#x430;&#x43A;&#x430; &#x43D;&#x430; <a href="https://en.wikipedia.org/wiki/Transport_layer?ref=igkuz.ru" rel="noopener">&#x442;&#x440;&#x430;&#x43D;&#x441;&#x43F;&#x43E;&#x440;&#x442;&#x43D;&#x43E;&#x43C;</a> &#x443;&#x440;&#x43E;&#x432;&#x43D;&#x435; (L4). <a href="https://en.wikipedia.org/wiki/SYN_flood?ref=igkuz.ru" rel="noopener">SYN flood</a>, <a href="https://en.wikipedia.org/wiki/UDP_flood_attack?ref=igkuz.ru" rel="noopener">UDP flood</a>.</li></ol><p>&#x415;&#x441;&#x43B;&#x438; &#x43E;&#x442; &#x43F;&#x435;&#x440;&#x432;&#x43E;&#x433;&#x43E; &#x440;&#x435;&#x430;&#x43B;&#x44C;&#x43D;&#x43E; &#x43E;&#x442;&#x431;&#x438;&#x442;&#x44C;&#x441;&#x44F;, &#x43D;&#x430;&#x441;&#x442;&#x440;&#x43E;&#x438;&#x432; &#x444;&#x438;&#x43B;&#x44C;&#x442;&#x440;&#x44B; &#x438;&#x43B;&#x438; WAF, &#x442;&#x43E; &#x43E;&#x442; &#x432;&#x442;&#x43E;&#x440;&#x43E;&#x433;&#x43E; &#x43D;&#x435; &#x432;&#x441;&#x435;&#x433;&#x434;&#x430;. UDP flood &#x43A;&#x440;&#x430;&#x439;&#x43D;&#x435; &#x44D;&#x444;&#x444;&#x435;&#x43A;&#x442;&#x438;&#x432;&#x435;&#x43D;. &#x417;&#x430;&#x43F;&#x440;&#x435;&#x442;&#x438;&#x442;&#x44C; UDP &#x43F;&#x430;&#x43A;&#x435;&#x442;&#x44B; &#x43C;&#x43E;&#x436;&#x43D;&#x43E; &#x442;&#x43E;&#x43B;&#x44C;&#x43A;&#x43E; &#x441; &#x43F;&#x43E;&#x43C;&#x43E;&#x449;&#x44C;&#x44E; &#x445;&#x43E;&#x441;&#x442;&#x435;&#x440;&#x430;.</p><p>&#x424;&#x43B;&#x43E;&#x443; &#x43E;&#x431;&#x44B;&#x447;&#x43D;&#x43E; &#x442;&#x430;&#x43A;&#x43E;&#x439;&#x200A;&#x2014;&#x200A;&#x431;&#x44C;&#x44E;&#x442; &#x432; &#x43F;&#x440;&#x438;&#x43B;&#x43E;&#x436;&#x435;&#x43D;&#x438;&#x435; (L7), &#x435;&#x441;&#x43B;&#x438; &#x43E;&#x442;&#x431;&#x438;&#x43B;&#x438;&#x441;&#x44C;, &#x442;&#x43E; &#x431;&#x44C;&#x44E;&#x442; &#x432; (L4), &#x435;&#x441;&#x43B;&#x438; &#x438; &#x442;&#x443;&#x442; &#x43E;&#x442;&#x431;&#x438;&#x43B;&#x438;&#x441;&#x44C;, &#x442;&#x43E; &#x443;&#x432;&#x435;&#x43B;&#x438;&#x447;&#x438;&#x432;&#x430;&#x44E;&#x442; &#x440;&#x430;&#x437;&#x43C;&#x435;&#x440;. &#x414;&#x430;&#x43B;&#x44C;&#x448;&#x435; &#x431;&#x44C;&#x44E;&#x442; &#x438; &#x432; L7 &#x438; &#x432; L4.</p><h4 id="--3">&#x41A;&#x430;&#x43A; &#x43E;&#x442;&#x431;&#x438;&#x432;&#x430;&#x43B;&#x438;&#x441;&#x44C;?</h4><ol><li>&#x41D;&#x430;&#x448;&#x43B;&#x438; &#x432; &#x43B;&#x43E;&#x433;&#x430;&#x445; &#x441;&#x435;&#x440;&#x432;&#x435;&#x440;&#x430; &#x43F;&#x430;&#x442;&#x442;&#x435;&#x440;&#x43D;&#x44B; &#x432; &#x437;&#x430;&#x43F;&#x440;&#x43E;&#x441;&#x430;&#x445; &#x43A; &#x43F;&#x440;&#x438;&#x43B;&#x43E;&#x436;&#x435;&#x43D;&#x438;&#x44E;. &#x412;&#x44B;&#x442;&#x430;&#x449;&#x438;&#x43B;&#x438; IP &#x430;&#x434;&#x440;&#x435;&#x441;&#x430; &#x438; &#x437;&#x430;&#x444;&#x438;&#x43B;&#x44C;&#x442;&#x440;&#x43E;&#x432;&#x430;&#x43B;&#x438; &#x442;&#x440;&#x430;&#x444;&#x438;&#x43A; &#x43D;&#x430; &#x431;&#x430;&#x43B;&#x430;&#x43D;&#x441;&#x435;&#x440;&#x435;.</li><li>&#x417;&#x430;&#x43F;&#x440;&#x435;&#x442;&#x438;&#x43B;&#x438; POST &#x442;&#x430;&#x43C;, &#x433;&#x434;&#x435; &#x43E;&#x43D; &#x43D;&#x435; &#x43D;&#x443;&#x436;&#x435;&#x43D;.</li><li>&#x41D;&#x430;&#x447;&#x430;&#x43B;&#x438; &#x441;&#x43D;&#x438;&#x43C;&#x430;&#x442;&#x44C; &#x434;&#x430;&#x43C;&#x43F; TCP &#x438; UDP &#x43F;&#x430;&#x43A;&#x435;&#x442;&#x43E;&#x432;. &#x41E;&#x431;&#x43D;&#x430;&#x440;&#x443;&#x436;&#x438;&#x43B;&#x438; UDP flood.</li><li>&#x421;&#x43E;&#x437;&#x432;&#x43E;&#x43D;&#x438;&#x43B;&#x438;&#x441;&#x44C; &#x441; &#x445;&#x43E;&#x441;&#x442;&#x435;&#x440;&#x43E;&#x43C; &#x438; &#x43F;&#x43E;&#x43F;&#x440;&#x43E;&#x441;&#x438;&#x43B;&#x438; &#x43E;&#x442;&#x43A;&#x43B;&#x44E;&#x447;&#x438;&#x442;&#x44C; UDP &#x442;&#x440;&#x430;&#x444;&#x438;&#x43A; &#x43A; &#x43D;&#x430;&#x448;&#x435;&#x43C;&#x443; IP. &#x41D;&#x43E; &#x43D;&#x430;&#x448; &#x43F;&#x440;&#x435;&#x43A;&#x440;&#x430;&#x441;&#x43D;&#x44B;&#x439; &#x445;&#x43E;&#x441;&#x442;&#x435;&#x440; &#x43D;&#x435; &#x441;&#x434;&#x435;&#x43B;&#x430;&#x43B; &#x44D;&#x442;&#x43E;&#x433;&#x43E;, &#x430; &#x43E;&#x442;&#x43F;&#x440;&#x430;&#x432;&#x438;&#x43B; &#x432; Null route. &#x41F;&#x440;&#x43E;&#x449;&#x435; &#x433;&#x43E;&#x432;&#x43E;&#x440;&#x44F;, &#x437;&#x430;&#x431;&#x43B;&#x43E;&#x43A;&#x438;&#x440;&#x43E;&#x432;&#x430;&#x43B; &#x432;&#x435;&#x441;&#x44C; &#x442;&#x440;&#x430;&#x444;&#x438;&#x43A; &#x43A; &#x43D;&#x430;&#x448;&#x435;&#x43C;&#x443; IP, &#x447;&#x442;&#x43E;&#x431;&#x44B; &#x437;&#x430;&#x449;&#x438;&#x442;&#x438;&#x442;&#x44C; &#x441;&#x432;&#x43E;&#x44E; &#x438;&#x43D;&#x444;&#x440;&#x430;&#x441;&#x442;&#x440;&#x443;&#x43A;&#x442;&#x443;&#x440;&#x443;, &#x438; &#x432;&#x44B;&#x43A;&#x43B;&#x44E;&#x447;&#x438;&#x43B; &#x43D;&#x430;&#x441;.</li><li>&#x41F;&#x435;&#x440;&#x435;&#x43A;&#x43B;&#x44E;&#x447;&#x438;&#x43B;&#x438; &#x43D;&#x430; &#x43D;&#x43E;&#x432;&#x44B;&#x439; IP &#x438; &#x43F;&#x43E;&#x434;&#x430;&#x43B;&#x438; &#x437;&#x430;&#x44F;&#x432;&#x43A;&#x438; &#x432; <a href="https://www.cloudflare.com/galileo/?ref=igkuz.ru" rel="noopener">CloudFlare Project Galileo</a> &#x438; <a href="https://projectshield.withgoogle.com/public/?ref=igkuz.ru" rel="noopener">Google Shield</a>.</li><li>&#x417;&#x430;&#x432;&#x435;&#x43B;&#x438; &#x430;&#x43A;&#x43A;&#x430;&#x443;&#x43D;&#x442; &#x438; &#x43E;&#x43F;&#x43B;&#x430;&#x442;&#x438;&#x43B;&#x438; &#x442;&#x430;&#x440;&#x438;&#x444; professional &#x432; CloudFlare.</li><li>&#x41F;&#x435;&#x440;&#x435;&#x43D;&#x435;&#x441;&#x43B;&#x438; &#x437;&#x43E;&#x43D;&#x443; &#x432; CloudFlare. &#x42D;&#x442;&#x43E; &#x431;&#x44B;&#x43B;&#x430; &#x441;&#x430;&#x43C;&#x430;&#x44F; &#x434;&#x43B;&#x438;&#x442;&#x435;&#x43B;&#x44C;&#x43D;&#x430;&#x44F; &#x43E;&#x43F;&#x435;&#x440;&#x430;&#x446;&#x438;&#x44F;. &#x417;&#x43E;&#x43D;&#x430; &#x43F;&#x435;&#x440;&#x435;&#x43D;&#x43E;&#x441;&#x438;&#x43B;&#x430;&#x441;&#x44C; 1,5 &#x447;&#x430;&#x441;&#x430;, &#x44D;&#x442;&#x43E; &#x432;&#x440;&#x435;&#x43C;&#x44F; &#x441;&#x430;&#x439;&#x442; &#x440;&#x430;&#x431;&#x43E;&#x442;&#x430;&#x43B; &#x441; &#x441;&#x438;&#x43B;&#x44C;&#x43D;&#x44B;&#x43C;&#x438; &#x43F;&#x435;&#x440;&#x435;&#x431;&#x43E;&#x44F;&#x43C;&#x438;. (&#x412;&#x43E;&#x442; <a href="https://developers.google.com/speed/public-dns/cache?hl=ru&amp;ref=igkuz.ru" rel="noopener">&#x442;&#x443;&#x442;</a> &#x43C;&#x43E;&#x436;&#x43D;&#x43E; &#x443;&#x441;&#x43A;&#x43E;&#x440;&#x438;&#x442;&#x44C; &#x43E;&#x431;&#x43D;&#x43E;&#x432;&#x43B;&#x435;&#x43D;&#x438;&#x435; &#x43F;&#x443;&#x431;&#x43B;&#x438;&#x447;&#x43D;&#x44B;&#x445; DNS).</li><li>&#x412;&#x43A;&#x43B;&#x44E;&#x447;&#x438;&#x43B;&#x438; &#x43C;&#x430;&#x433;&#x438;&#x447;&#x435;&#x441;&#x43A;&#x443;&#x44E; &#x43A;&#x43D;&#x43E;&#x43F;&#x43A;&#x443; Under Attack. &#x42D;&#x442;&#x43E; javascript challenge &#x438; &#x430;&#x433;&#x440;&#x435;&#x441;&#x441;&#x438;&#x432;&#x43D;&#x430;&#x44F; &#x444;&#x438;&#x43B;&#x44C;&#x442;&#x440;&#x430;&#x446;&#x438;&#x44F; &#x437;&#x430;&#x43F;&#x440;&#x43E;&#x441;&#x43E;&#x432;. &#x414;&#x43E; &#x432;&#x445;&#x43E;&#x434;&#x430; &#x43D;&#x430; &#x441;&#x430;&#x439;&#x442; &#x43F;&#x43E;&#x43A;&#x430;&#x437;&#x44B;&#x432;&#x430;&#x435;&#x442;&#x441;&#x44F; &#x441;&#x442;&#x440;&#x430;&#x43D;&#x438;&#x446;&#x430;, &#x43D;&#x430; &#x43A;&#x43E;&#x442;&#x43E;&#x440;&#x43E;&#x439; &#x434;&#x43E;&#x43B;&#x436;&#x435;&#x43D; &#x43E;&#x442;&#x440;&#x430;&#x431;&#x43E;&#x442;&#x430;&#x442;&#x44C; js &#x441;&#x43A;&#x440;&#x438;&#x43F;&#x442; &#x438; &#x441;&#x440;&#x435;&#x434;&#x438;&#x440;&#x435;&#x43A;&#x442;&#x438;&#x442;&#x44C; &#x43F;&#x43E;&#x43B;&#x44C;&#x437;&#x43E;&#x432;&#x430;&#x442;&#x435;&#x43B;&#x44F; &#x447;&#x435;&#x440;&#x435;&#x437; 5 &#x441;&#x435;&#x43A;&#x443;&#x43D;&#x434;.</li><li>&#x412;&#x43A;&#x43B;&#x44E;&#x447;&#x438;&#x43B;&#x438; rate limit &#x43D;&#x430; &#x43A;&#x43E;&#x43B;&#x438;&#x447;&#x435;&#x441;&#x442;&#x432;&#x43E; &#x437;&#x430;&#x43F;&#x440;&#x43E;&#x441;&#x43E;&#x432; &#x441; &#x43E;&#x434;&#x43D;&#x43E;&#x433;&#x43E; IP &#x438; &#x43E;&#x442;&#x43A;&#x43B;&#x44E;&#x447;&#x438;&#x43B;&#x438; &#x442;&#x430;&#x43A;&#x443;&#x44E; &#x436;&#x435; &#x43D;&#x430;&#x441;&#x442;&#x440;&#x43E;&#x439;&#x43A;&#x443; &#x43D;&#x430; nginx.</li><li>&#x412;&#x43A;&#x43B;&#x44E;&#x447;&#x438;&#x43B;&#x438; WAF (Web Application Firewall) &#x43E;&#x442; CloudFlare. &#x41F;&#x43E;&#x441;&#x43B;&#x435;&#x434;&#x443;&#x44E;&#x449;&#x430;&#x44F; &#x43D;&#x430;&#x441;&#x442;&#x440;&#x43E;&#x439;&#x43A;&#x430; WAF &#x434;&#x43B;&#x44F; &#x438;&#x437;&#x434;&#x430;&#x43D;&#x438;&#x44F; &#x437;&#x430;&#x43D;&#x44F;&#x43B;&#x430; &#x43F;&#x440;&#x438;&#x43C;&#x435;&#x440;&#x43D;&#x43E; 3 &#x434;&#x43D;&#x44F;. &#x42D;&#x442;&#x43E; &#x43E;&#x442;&#x441;&#x43B;&#x435;&#x436;&#x438;&#x432;&#x430;&#x43D;&#x438;&#x435; &#x437;&#x430;&#x43F;&#x440;&#x43E;&#x441;&#x43E;&#x432; &#x438; &#x440;&#x430;&#x431;&#x43E;&#x442;&#x44B; &#x440;&#x435;&#x434;&#x430;&#x43A;&#x446;&#x438;&#x438;, &#x43E;&#x442;&#x43A;&#x43B;&#x44E;&#x447;&#x435;&#x43D;&#x438;&#x435; &#x447;&#x430;&#x441;&#x442;&#x438; &#x444;&#x438;&#x43B;&#x44C;&#x442;&#x440;&#x43E;&#x432; &#x438; &#x430;&#x434;&#x430;&#x43F;&#x442;&#x430;&#x446;&#x438;&#x44F; &#x43F;&#x43E;&#x434; &#x43D;&#x430;&#x448;&#x443; &#x441;&#x438;&#x441;&#x442;&#x435;&#x43C;&#x443;.</li><li>&#x41D;&#x430;&#x441;&#x442;&#x440;&#x43E;&#x438;&#x43B;&#x438; nginx, &#x447;&#x442;&#x43E;&#x431;&#x44B; &#x43D;&#x435; &#x431;&#x43B;&#x43E;&#x43A;&#x438;&#x440;&#x43E;&#x432;&#x430;&#x442;&#x44C; &#x437;&#x430;&#x43F;&#x440;&#x43E;&#x441;&#x44B; &#x43E;&#x442; &#x43F;&#x43E;&#x434;&#x441;&#x435;&#x442;&#x438; CloudFlare &#x438; &#x43F;&#x440;&#x43E;&#x43A;&#x438;&#x434;&#x44B;&#x432;&#x430;&#x442;&#x44C; &#x440;&#x435;&#x430;&#x43B;&#x44C;&#x43D;&#x44B;&#x435; IP &#x43F;&#x43E;&#x43B;&#x44C;&#x437;&#x43E;&#x432;&#x430;&#x442;&#x435;&#x43B;&#x435;&#x439; &#x432; &#x441;&#x438;&#x441;&#x442;&#x435;&#x43C;&#x443;.</li></ol><p>&#x41A;&#x430;&#x43A; &#x438;&#x442;&#x43E;&#x433;, &#x438;&#x437;&#x434;&#x430;&#x43D;&#x438;&#x435; &#x431;&#x44B;&#x43B;&#x43E; &#x43D;&#x435;&#x434;&#x43E;&#x441;&#x442;&#x443;&#x43F;&#x43D;&#x43E; &#x432; &#x441;&#x443;&#x43C;&#x43C;&#x435; &#x43E;&#x43A;&#x43E;&#x43B;&#x43E; 2&#x445; &#x447;&#x430;&#x441;&#x43E;&#x432;&#x200A;&#x2014;&#x200A;&#x447;&#x442;&#x43E; &#x443;&#x43A;&#x43B;&#x430;&#x434;&#x44B;&#x432;&#x430;&#x435;&#x442;&#x441;&#x44F; &#x432; SLA.</p><h4 id="--4">&#x422;&#x430;&#x439;&#x43C;&#x438;&#x43D;&#x433;&#x438;</h4><p>&#x412; &#x441;&#x440;&#x435;&#x434;&#x43D;&#x435;&#x43C; &#x431;&#x43E;&#x442;&#x43D;&#x435;&#x442; &#x436;&#x438;&#x432;&#x435;&#x442; 1,5&#x2013;2 &#x43D;&#x435;&#x434;&#x435;&#x43B;&#x438;. &#x425;&#x43E;&#x441;&#x442;&#x435;&#x440;&#x44B; &#x437;&#x430;&#x431;&#x43B;&#x43E;&#x43A;&#x438;&#x440;&#x443;&#x44E;&#x442; &#x432;&#x437;&#x43B;&#x43E;&#x43C;&#x430;&#x43D;&#x43D;&#x44B;&#x435; &#x43C;&#x430;&#x448;&#x438;&#x43D;&#x44B;, &#x441; &#x43A;&#x43E;&#x442;&#x43E;&#x440;&#x44B;&#x445; &#x438;&#x434;&#x435;&#x442; &#x43F;&#x43E;&#x434;&#x43E;&#x437;&#x440;&#x438;&#x442;&#x435;&#x43B;&#x44C;&#x43D;&#x44B;&#x439; &#x442;&#x440;&#x430;&#x444;&#x438;&#x43A;, &#x438;&#x43B;&#x438; &#x430;&#x442;&#x430;&#x43A;&#x443;&#x44E;&#x449;&#x438;&#x43C; &#x43F;&#x440;&#x43E;&#x441;&#x442;&#x43E; &#x43D;&#x430;&#x434;&#x43E;&#x435;&#x441;&#x442;.</p><p>&#x412;&#x44B;&#x43C;&#x43E;&#x433;&#x430;&#x442;&#x435;&#x43B;&#x438; &#x430;&#x442;&#x430;&#x43A;&#x43E;&#x432;&#x430;&#x43B;&#x438; &#x43D;&#x435;&#x434;&#x435;&#x43B;&#x44E;, &#x431;&#x438;&#x43B;&#x438; &#x43F;&#x43E; 2&#x2013;3 &#x447;&#x430;&#x441;&#x430; &#x432; &#x43F;&#x438;&#x43A;&#x43E;&#x432;&#x43E;&#x435; &#x43F;&#x43E; &#x442;&#x440;&#x430;&#x444;&#x438;&#x43A;&#x443; &#x432;&#x440;&#x435;&#x43C;&#x44F;, &#x430; &#x442;&#x430;&#x43A;&#x436;&#x435; &#x43D;&#x43E;&#x447;&#x44C;&#x44E; &#x438; &#x440;&#x430;&#x43D;&#x43E; &#x443;&#x442;&#x440;&#x43E;&#x43C;. &#x41D;&#x430; &#x434;&#x440;&#x443;&#x433;&#x43E;&#x43C; &#x438;&#x437;&#x434;&#x430;&#x43D;&#x438;&#x438; &#x432;&#x43A;&#x43B;&#x44E;&#x447;&#x438;&#x43B;&#x438; &#x432; 12:00 &#x438; &#x434;&#x435;&#x440;&#x436;&#x430;&#x43B;&#x438; &#x434;&#x43E; 16:30 &#x441;&#x43B;&#x435;&#x434;&#x443;&#x44E;&#x449;&#x435;&#x433;&#x43E; &#x434;&#x43D;&#x44F;. &#x41F;&#x440;&#x438;&#x447;&#x438;&#x43D;&#x44B; &#x438; &#x446;&#x435;&#x43B;&#x438; &#x43E;&#x441;&#x442;&#x430;&#x43B;&#x438;&#x441;&#x44C; &#x43D;&#x435;&#x438;&#x437;&#x432;&#x435;&#x441;&#x442;&#x43D;&#x44B;&#x43C;&#x438;.</p><p>CloudFlare &#x432;&#x43A;&#x43B;&#x44E;&#x447;&#x438;&#x43B; &#x432; &#x43F;&#x440;&#x43E;&#x433;&#x440;&#x430;&#x43C;&#x43C;&#x443; Galileo &#x432; &#x442;&#x435;&#x447;&#x435;&#x43D;&#x438;&#x435; &#x434;&#x432;&#x443;&#x445; &#x434;&#x43D;&#x435;&#x439;. &#x417;&#x430;&#x449;&#x438;&#x442;&#x430; &#x43D;&#x430; &#x442;&#x430;&#x440;&#x438;&#x444;&#x435; professional &#x431;&#x44B;&#x43B;&#x430; &#x441;&#x440;&#x430;&#x437;&#x443;, &#x43D;&#x43E; &#x431;&#x435;&#x441;&#x43F;&#x43B;&#x430;&#x442;&#x43D;&#x43E;&#x439; &#x435;&#x451; &#x441;&#x434;&#x435;&#x43B;&#x430;&#x43B;&#x438; &#x441;&#x43F;&#x443;&#x441;&#x442;&#x44F; &#x434;&#x432;&#x430; &#x434;&#x43D;&#x44F;.</p><p>Google Shield &#x434;&#x430;&#x43B; &#x434;&#x43E;&#x441;&#x442;&#x443;&#x43F; &#x43A; &#x441;&#x432;&#x43E;&#x435;&#x43C;&#x443; &#x441;&#x435;&#x440;&#x432;&#x438;&#x441;&#x443; &#x441;&#x43F;&#x443;&#x441;&#x442;&#x44F; &#x442;&#x440;&#x438; &#x434;&#x43D;&#x44F;. &#x41A; &#x442;&#x43E;&#x43C;&#x443; &#x432;&#x440;&#x435;&#x43C;&#x435;&#x43D;&#x438; &#x43C;&#x44B; &#x443;&#x436;&#x435; &#x443;&#x435;&#x445;&#x430;&#x43B;&#x438; &#x437;&#x430; &#x449;&#x438;&#x442; CloudFlare.</p><h4 id="--5">&#x427;&#x442;&#x43E; &#x441;&#x434;&#x435;&#x43B;&#x430;&#x442;&#x44C; &#x441;&#x440;&#x430;&#x437;&#x443; &#x43F;&#x43E;&#x441;&#x43B;&#x435; &#x43F;&#x440;&#x43E;&#x447;&#x442;&#x435;&#x43D;&#x438;&#x44F; &#x44D;&#x442;&#x43E;&#x433;&#x43E; &#x442;&#x435;&#x43A;&#x441;&#x442;&#x430;?</h4><ol><li>&#x41F;&#x440;&#x43E;&#x432;&#x435;&#x440;&#x438;&#x442;&#x44C; TTL &#x432; &#x43A;&#x440;&#x438;&#x442;&#x438;&#x447;&#x43D;&#x44B;&#x445; DNS &#x437;&#x430;&#x43F;&#x438;&#x441;&#x44F;&#x445; (&#x441;&#x434;&#x435;&#x43B;&#x430;&#x439;&#x442;&#x435; &#x445;&#x43E;&#x442;&#x44F; &#x431;&#x44B; 900-1800). &#x42D;&#x442;&#x43E; 15&#x2013;30 &#x43C;&#x438;&#x43D;. &#x421;&#x442;&#x43E;&#x440;&#x43E;&#x43D;&#x43D;&#x438;&#x439; DNS &#x445;&#x43E;&#x441;&#x442;&#x438;&#x43D;&#x433; &#x43D;&#x435; &#x443;&#x43C;&#x440;&#x435;&#x442; &#x43E;&#x442; &#x442;&#x430;&#x43A;&#x43E;&#x433;&#x43E; TTL, self-hosted &#x43D;&#x430;&#x434;&#x43E; &#x441;&#x43C;&#x43E;&#x442;&#x440;&#x435;&#x442;&#x44C; &#x438; &#x43F;&#x43E;&#x43C;&#x43D;&#x438;&#x442;&#x44C; &#x43E; &#x440;&#x435;&#x437;&#x435;&#x440;&#x432;&#x438;&#x440;&#x43E;&#x432;&#x430;&#x43D;&#x438;&#x438; &#x441;&#x435;&#x440;&#x432;&#x438;&#x441;&#x430;. &#x41D;&#x438;&#x437;&#x43A;&#x438;&#x439; TTL &#x43F;&#x43E;&#x437;&#x432;&#x43E;&#x43B;&#x438;&#x442; &#x431;&#x44B;&#x441;&#x442;&#x440;&#x43E; &#x43C;&#x435;&#x43D;&#x44F;&#x442;&#x44C; IP &#x438; &#x431;&#x44B;&#x441;&#x442;&#x440;&#x435;&#x435; &#x432;&#x441;&#x442;&#x430;&#x442;&#x44C; &#x43F;&#x43E;&#x441;&#x43B;&#x435; &#x43F;&#x435;&#x440;&#x435;&#x43D;&#x43E;&#x441;&#x430; &#x437;&#x43E;&#x43D;&#x44B;.</li><li>&#x41A;&#x443;&#x43F;&#x438;&#x442;&#x435; IP &#x43F;&#x43E;&#x434;&#x441;&#x435;&#x442;&#x44C;. &#x421;&#x442;&#x43E;&#x438;&#x442; &#x43A;&#x43E;&#x43F;&#x435;&#x439;&#x43A;&#x438;, &#x435;&#x441;&#x43B;&#x438; &#x443;&#x445;&#x43E;&#x434;&#x438;&#x442;&#x44C; &#x437;&#x430; &#x432;&#x43D;&#x435;&#x448;&#x43D;&#x438;&#x439; &#x449;&#x438;&#x442;, &#x442;&#x43E; &#x43D;&#x443;&#x436;&#x43D;&#x43E; &#x43C;&#x435;&#x43D;&#x44F;&#x442;&#x44C; IP &#x438; &#x432;&#x44B;&#x43A;&#x43B;&#x44E;&#x447;&#x430;&#x442;&#x44C; &#x441;&#x442;&#x430;&#x440;&#x44B;&#x439;. &#x411;&#x443;&#x434;&#x435;&#x442;&#x435; &#x43E;&#x442;&#x431;&#x438;&#x432;&#x430;&#x442;&#x44C;&#x441;&#x44F; &#x441;&#x430;&#x43C;&#x438;, &#x432;&#x43E;&#x437;&#x43C;&#x43E;&#x436;&#x43D;&#x43E;&#x441;&#x442;&#x44C; &#x43C;&#x435;&#x43D;&#x44F;&#x442;&#x44C; IP &#x434;&#x430;&#x441;&#x442; &#x432;&#x440;&#x435;&#x43C;&#x44F; &#x434;&#x43B;&#x44F; &#x43C;&#x430;&#x43D;&#x435;&#x432;&#x440;&#x43E;&#x432;.</li><li>&#x41F;&#x43E;&#x434;&#x430;&#x439;&#x442;&#x435; &#x437;&#x430;&#x44F;&#x432;&#x43A;&#x438; &#x432; <a href="https://www.cloudflare.com/?ref=igkuz.ru" rel="noopener">CloudFlare</a> &#x438; <a href="https://projectshield.withgoogle.com/?ref=igkuz.ru" rel="noopener">GoogleShield</a>. &#x42D;&#x442;&#x43E; &#x441;&#x435;&#x440;&#x432;&#x438;&#x441;&#x44B; &#x43F;&#x43E; &#x437;&#x430;&#x449;&#x438;&#x442;&#x435; &#x43C;&#x435;&#x434;&#x438;&#x430;. &#x41F;&#x43B;&#x44E;&#x441;&#x44B; &#x438; &#x43C;&#x438;&#x43D;&#x443;&#x441;&#x44B; &#x43A;&#x430;&#x436;&#x434;&#x43E;&#x433;&#x43E; &#x440;&#x430;&#x441;&#x43F;&#x438;&#x448;&#x443; &#x432; &#x43E;&#x442;&#x434;&#x435;&#x43B;&#x44C;&#x43D;&#x43E;&#x439; &#x441;&#x442;&#x430;&#x442;&#x44C;&#x435;. &#x412; &#x43A;&#x440;&#x430;&#x442;&#x446;&#x435;, &#x443; Shield &#x431;&#x44B;&#x441;&#x442;&#x440;&#x435;&#x435; &#x441;&#x435;&#x442;&#x430;&#x43F;, &#x43D;&#x43E; &#x445;&#x443;&#x436;&#x435; &#x437;&#x430;&#x449;&#x438;&#x442;&#x430;.</li></ol><p>&#x41D;&#x435; &#x43D;&#x443;&#x436;&#x43D;&#x43E; &#x431;&#x440;&#x43E;&#x441;&#x430;&#x442;&#x44C;&#x441;&#x44F; &#x43F;&#x435;&#x440;&#x435;&#x43F;&#x438;&#x441;&#x44B;&#x432;&#x430;&#x442;&#x44C; &#x43F;&#x440;&#x438;&#x43B;&#x43E;&#x436;&#x435;&#x43D;&#x438;&#x435; &#x438;&#x43B;&#x438; &#x43D;&#x430;&#x440;&#x430;&#x449;&#x438;&#x432;&#x430;&#x442;&#x44C; &#x43C;&#x43E;&#x449;&#x43D;&#x43E;&#x441;&#x442;&#x44C; &#x43C;&#x430;&#x448;&#x438;&#x43D;. &#x41F;&#x440;&#x438;&#x43B;&#x43E;&#x436;&#x435;&#x43D;&#x438;&#x435; &#x431;&#x44B;&#x441;&#x442;&#x440;&#x43E; &#x43D;&#x435; &#x43F;&#x435;&#x440;&#x435;&#x43F;&#x438;&#x448;&#x438;&#x442;&#x435;, &#x430; &#x43C;&#x430;&#x448;&#x438;&#x43D;&#x44B; &#x43D;&#x435; &#x43F;&#x43E;&#x43C;&#x43E;&#x433;&#x443;&#x442;.</p><h4 id="--6">&#x41A;&#x430;&#x43A;&#x438;&#x435; &#x441;&#x435;&#x440;&#x432;&#x438;&#x441;&#x44B; &#x43C;&#x43E;&#x436;&#x43D;&#x43E; &#x438;&#x441;&#x43F;&#x43E;&#x43B;&#x44C;&#x437;&#x43E;&#x432;&#x430;&#x442;&#x44C;?</h4><p><em>&#x411;&#x435;&#x441;&#x43F;&#x43B;&#x430;&#x442;&#x43D;&#x44B;&#x435;</em></p><ol><li>CloudFlare Project Gallileo</li><li>Google Shield</li></ol><p><em>&#x41F;&#x43B;&#x430;&#x442;&#x43D;&#x44B;&#x435;</em></p><ol><li><a href="https://qrator.net/en/?ref=igkuz.ru" rel="noopener">Qrator</a></li><li><a href="https://www.akamai.com/uk/en/products/cloud-security/kona-site-defender.jsp?ref=igkuz.ru" rel="noopener">Kona Site Defender</a> &#x43E;&#x442; Akamai</li></ol><p>&#x421;&#x435;&#x440;&#x432;&#x438;&#x441;&#x43E;&#x432; &#x43F;&#x43E; &#x437;&#x430;&#x449;&#x438;&#x442;&#x435; &#x43E;&#x442; DDoS &#x430;&#x442;&#x430;&#x43A; &#x43D;&#x430;&#x43C;&#x43D;&#x43E;&#x433;&#x43E; &#x431;&#x43E;&#x43B;&#x44C;&#x448;&#x435;, &#x44F; &#x43B;&#x438;&#x448;&#x44C; &#x43F;&#x435;&#x440;&#x435;&#x447;&#x438;&#x441;&#x43B;&#x438;&#x43B; &#x43E;&#x442; &#x438;&#x437;&#x432;&#x435;&#x441;&#x442;&#x43D;&#x44B;&#x445; &#x43A;&#x43E;&#x43C;&#x43F;&#x430;&#x43D;&#x438;&#x439; &#x438; &#x434;&#x43E;&#x431;&#x430;&#x432;&#x438;&#x43B; &#x440;&#x43E;&#x441;&#x441;&#x438;&#x439;&#x441;&#x43A;&#x43E;&#x433;&#x43E; &#x432;&#x435;&#x43D;&#x434;&#x43E;&#x440;&#x430;.</p><h4 id="--7">&#x425;&#x43E;&#x441;&#x442;&#x438;&#x43D;&#x433;</h4><p>&#x41E;&#x434;&#x43D;&#x430; &#x438;&#x437; &#x441;&#x430;&#x43C;&#x44B;&#x445; &#x432;&#x430;&#x436;&#x43D;&#x44B;&#x445; &#x441;&#x43E;&#x441;&#x442;&#x430;&#x432;&#x43B;&#x44F;&#x44E;&#x449;&#x438;&#x445; &#x438;&#x43D;&#x444;&#x440;&#x430;&#x441;&#x442;&#x440;&#x443;&#x43A;&#x442;&#x443;&#x440;&#x44B;. &#x41F;&#x43E;&#x434;&#x445;&#x43E;&#x434;&#x438;&#x442;&#x44C; &#x43A; &#x432;&#x44B;&#x431;&#x43E;&#x440;&#x443; &#x43D;&#x430;&#x434;&#x43E; &#x43E;&#x447;&#x435;&#x43D;&#x44C; &#x430;&#x43A;&#x43A;&#x443;&#x440;&#x430;&#x442;&#x43D;&#x43E;, &#x43E;&#x441;&#x43E;&#x431;&#x435;&#x43D;&#x43D;&#x43E; &#x435;&#x441;&#x43B;&#x438; &#x432;&#x44B; &#x43C;&#x435;&#x434;&#x438;&#x430; &#x438; &#x43D;&#x430; &#x432;&#x430;&#x441; &#x435;&#x441;&#x442;&#x44C; &#x437;&#x430;&#x43A;&#x43E;&#x43D;&#x43E;&#x434;&#x430;&#x442;&#x435;&#x43B;&#x44C;&#x43D;&#x44B;&#x435; &#x43E;&#x433;&#x440;&#x430;&#x43D;&#x438;&#x447;&#x435;&#x43D;&#x438;&#x44F;. &#x412;&#x43D;&#x438;&#x43C;&#x430;&#x442;&#x435;&#x43B;&#x44C;&#x43D;&#x43E; &#x438;&#x437;&#x443;&#x447;&#x430;&#x439;&#x442;&#x435; &#x434;&#x43E;&#x43A;&#x443;&#x43C;&#x435;&#x43D;&#x442;&#x430;&#x446;&#x438;&#x44E; &#x43D;&#x430; &#x441;&#x430;&#x439;&#x442;&#x435; &#x445;&#x43E;&#x441;&#x442;&#x438;&#x43D;&#x433;&#x430; &#x438; &#x441;&#x43C;&#x43E;&#x442;&#x440;&#x438;&#x442;&#x435; &#x435;&#x441;&#x442;&#x44C; &#x43B;&#x438; &#x437;&#x430;&#x449;&#x438;&#x442;&#x430; &#x43E;&#x442; DDoS &#x430;&#x442;&#x430;&#x43A;. &#x41F;&#x43B;&#x430;&#x442;&#x43D;&#x430;&#x44F; &#x438;&#x43B;&#x438; &#x431;&#x435;&#x441;&#x43F;&#x43B;&#x430;&#x442;&#x43D;&#x430;&#x44F; &#x438; &#x447;&#x442;&#x43E; &#x438;&#x43C;&#x435;&#x43D;&#x43D;&#x43E; &#x445;&#x43E;&#x441;&#x442;&#x435;&#x440; &#x43F;&#x43E;&#x434; &#x44D;&#x442;&#x438;&#x43C; &#x43F;&#x43E;&#x43D;&#x438;&#x43C;&#x430;&#x435;&#x442;. &#x421;&#x43E;&#x432;&#x435;&#x442;&#x443;&#x44E; &#x43D;&#x435; &#x43F;&#x43E;&#x43B;&#x435;&#x43D;&#x438;&#x442;&#x44C;&#x441;&#x44F; &#x438; &#x43F;&#x43E;&#x437;&#x432;&#x43E;&#x43D;&#x438;&#x442;&#x44C;. &#x41A;&#x43E;&#x43D;&#x441;&#x443;&#x43B;&#x44C;&#x442;&#x430;&#x43D;&#x442;&#x44B; &#x43D;&#x430; &#x43B;&#x438;&#x43D;&#x438;&#x438; &#x43C;&#x43E;&#x433;&#x443;&#x442; &#x43F;&#x435;&#x440;&#x435;&#x43A;&#x43B;&#x44E;&#x447;&#x438;&#x442;&#x44C; &#x43D;&#x430; &#x442;&#x435;&#x445;&#x43D;&#x430;&#x440;&#x435;&#x439;, &#x43A;&#x43E;&#x442;&#x43E;&#x440;&#x44B;&#x435; &#x441;&#x43C;&#x43E;&#x433;&#x443;&#x442; &#x431;&#x43E;&#x43B;&#x435;&#x435; &#x442;&#x43E;&#x447;&#x43D;&#x43E; &#x440;&#x430;&#x441;&#x441;&#x43A;&#x430;&#x437;&#x430;&#x442;&#x44C; &#x43A;&#x430;&#x43A;&#x43E;&#x439; &#x443;&#x440;&#x43E;&#x432;&#x435;&#x43D;&#x44C; &#x430;&#x442;&#x430;&#x43A;&#x438; &#x445;&#x43E;&#x441;&#x442;&#x435;&#x440; &#x432;&#x44B;&#x434;&#x435;&#x440;&#x436;&#x438;&#x442; &#x438; &#x43A;&#x430;&#x43A; &#x441;&#x43C;&#x43E;&#x436;&#x435;&#x442; &#x432;&#x430;&#x43C; &#x43F;&#x43E;&#x43C;&#x43E;&#x447;&#x44C;.</p><p>&#x41C;&#x44B; &#x438;&#x441;&#x43F;&#x43E;&#x43B;&#x44C;&#x437;&#x43E;&#x432;&#x430;&#x43B;&#x438; Softlayer (IBM), &#x432;&#x441;&#x451; &#x447;&#x442;&#x43E; &#x441;&#x434;&#x435;&#x43B;&#x430;&#x43B;&#x438; &#x44D;&#x442;&#x438; &#x440;&#x435;&#x431;&#x44F;&#x442;&#x430;, &#x442;&#x430;&#x43A; &#x44D;&#x442;&#x43E; &#x43E;&#x442;&#x43F;&#x440;&#x430;&#x432;&#x438;&#x43B;&#x438; &#x432; null route &#x431;&#x435;&#x437; &#x440;&#x430;&#x437;&#x433;&#x43E;&#x432;&#x43E;&#x440;&#x43E;&#x432;. &#x414;&#x430;&#x436;&#x435; &#x43F;&#x440;&#x43E;&#x441;&#x442;&#x430;&#x44F; &#x43F;&#x440;&#x43E;&#x441;&#x44C;&#x431;&#x430; &#x43E;&#x442;&#x43A;&#x43B;&#x44E;&#x447;&#x438;&#x442;&#x44C; &#x432;&#x435;&#x441;&#x44C; UDP &#x442;&#x440;&#x430;&#x444;&#x438;&#x43A; &#x434;&#x43E; &#x43D;&#x430;&#x448;&#x438;&#x445; &#x43C;&#x430;&#x448;&#x438;&#x43D; &#x431;&#x44B;&#x43B;&#x430; &#x43F;&#x440;&#x43E;&#x438;&#x433;&#x43D;&#x43E;&#x440;&#x438;&#x440;&#x43E;&#x432;&#x430;&#x43D;&#x430;. &#x425;&#x43E;&#x442;&#x44C; Softlayer &#x43F;&#x440;&#x435;&#x434;&#x43E;&#x441;&#x442;&#x430;&#x432;&#x43B;&#x44F;&#x435;&#x442; &#x441;&#x430;&#x43C;&#x44B;&#x439; &#x431;&#x43E;&#x43B;&#x44C;&#x448;&#x43E;&#x439; &#x444;&#x443;&#x43D;&#x43A;&#x446;&#x438;&#x43E;&#x43D;&#x430;&#x43B; &#x43F;&#x43E; &#x440;&#x430;&#x431;&#x43E;&#x442;&#x435; &#x441; &#x441;&#x435;&#x442;&#x44C;&#x44E;, &#x432;&#x441;&#x435; &#x436;&#x435; &#x43E;&#x442;&#x441;&#x443;&#x442;&#x441;&#x442;&#x432;&#x438;&#x435; &#x437;&#x430;&#x449;&#x438;&#x442;&#x44B; &#x43E;&#x442; DDoS &#x430;&#x442;&#x430;&#x43A; &#x438; &#x43D;&#x435;&#x436;&#x435;&#x43B;&#x430;&#x43D;&#x438;&#x44F; &#x43F;&#x43E;&#x43C;&#x43E;&#x433;&#x430;&#x442;&#x44C; &#x437;&#x430;&#x441;&#x442;&#x430;&#x432;&#x438;&#x43B;&#x438; &#x43D;&#x430;&#x441; &#x438;&#x441;&#x43A;&#x430;&#x442;&#x44C; &#x434;&#x440;&#x443;&#x433;&#x438;&#x435; &#x432;&#x430;&#x440;&#x438;&#x430;&#x43D;&#x442;&#x44B;.</p><p>&#x421;&#x43E;&#x432;&#x435;&#x442;&#x443;&#x44E; &#x43F;&#x43E;&#x441;&#x43C;&#x43E;&#x442;&#x440;&#x435;&#x442;&#x44C; &#x432; &#x441;&#x442;&#x43E;&#x440;&#x43E;&#x43D;&#x443; Hetzner, Online.net &#x438; OVH. &#x42D;&#x442;&#x43E; &#x43A;&#x440;&#x443;&#x43F;&#x43D;&#x44B;&#x435; &#x43A;&#x43E;&#x43C;&#x43F;&#x430;&#x43D;&#x438;&#x438;, &#x43A;&#x43E;&#x442;&#x43E;&#x440;&#x44B;&#x435; &#x43F;&#x440;&#x435;&#x434;&#x43E;&#x441;&#x442;&#x430;&#x432;&#x43B;&#x44F;&#x44E;&#x442; &#x437;&#x430;&#x449;&#x438;&#x442;&#x443; &#x43E;&#x442; DDoS. &#x420;&#x43E;&#x441;&#x441;&#x438;&#x439;&#x441;&#x43A;&#x438;&#x445; &#x445;&#x43E;&#x441;&#x442;&#x435;&#x440;&#x43E;&#x432; &#x43D;&#x435; &#x441;&#x43C;&#x43E;&#x442;&#x440;&#x435;&#x43B;, &#x43D;&#x43E; &#x434;&#x443;&#x43C;&#x430;&#x44E; &#x442;&#x430;&#x43C; &#x442;&#x43E;&#x436;&#x435; &#x435;&#x441;&#x442;&#x44C; &#x438;&#x433;&#x440;&#x43E;&#x43A;&#x438; &#x441; &#x43D;&#x443;&#x436;&#x43D;&#x44B;&#x43C;&#x438; &#x43E;&#x43F;&#x446;&#x438;&#x44F;&#x43C;&#x438;. Hetzner &#x43F;&#x440;&#x435;&#x434;&#x43E;&#x441;&#x442;&#x430;&#x432;&#x43B;&#x44F;&#x435;&#x442; &#x443;&#x441;&#x43B;&#x43E;&#x432;&#x43D;&#x43E; &#x431;&#x435;&#x441;&#x43F;&#x43B;&#x430;&#x442;&#x43D;&#x43E;. &#x41A;&#x430;&#x447;&#x435;&#x441;&#x442;&#x432;&#x43E; &#x438; &#x433;&#x440;&#x430;&#x43D;&#x438;&#x446;&#x44B; &#x43D;&#x435; &#x43F;&#x440;&#x43E;&#x432;&#x435;&#x440;&#x44F;&#x43B;.</p><h4 id="--8">&#x427;&#x442;&#x43E; &#x434;&#x435;&#x43B;&#x430;&#x442;&#x44C; &#x435;&#x441;&#x43B;&#x438; &#x432;&#x44B; &#x441;&#x435;&#x439;&#x447;&#x430;&#x441; &#x43F;&#x43E;&#x434; &#x430;&#x442;&#x430;&#x43A;&#x43E;&#x439;?</h4><p>&#x412;&#x43E;-&#x43F;&#x435;&#x440;&#x432;&#x44B;&#x445;, &#x432;&#x44B;&#x434;&#x43E;&#x445;&#x43D;&#x443;&#x442;&#x44C;. &#x41D;&#x430; &#x432;&#x430;&#x441; &#x443;&#x436;&#x435; &#x43D;&#x430;&#x43F;&#x430;&#x43B;&#x438; &#x438; &#x435;&#x441;&#x43B;&#x438; &#x43F;&#x43E;&#x434;&#x433;&#x43E;&#x442;&#x43E;&#x432;&#x43A;&#x438; &#x431;&#x44B;&#x43B;&#x43E; 0, &#x442;&#x43E; &#x440;&#x432;&#x430;&#x442;&#x44C; &#x432;&#x43E;&#x43B;&#x43E;&#x441;&#x44B; &#x43D;&#x430; &#x433;&#x43E;&#x43B;&#x43E;&#x432;&#x435; &#x438;&#x43B;&#x438; &#x436;&#x43E;&#x43F;&#x435; &#x443;&#x436;&#x435; &#x431;&#x435;&#x441;&#x43F;&#x43E;&#x43B;&#x435;&#x437;&#x43D;&#x43E;.</p><p>&#x412;&#x43E;-&#x432;&#x442;&#x43E;&#x440;&#x44B;&#x445;, &#x43F;&#x43E;&#x43D;&#x44F;&#x442;&#x44C; &#x43F;&#x440;&#x43E;&#x431;&#x43B;&#x435;&#x43C;&#x443;:</p><ol><li>&#x412;&#x435;&#x43A;&#x442;&#x43E;&#x440; &#x430;&#x442;&#x430;&#x43A;&#x438;.</li><li>&#x41C;&#x430;&#x441;&#x448;&#x442;&#x430;&#x431; &#x442;&#x440;&#x430;&#x433;&#x435;&#x434;&#x438;&#x438;.</li></ol><p>L7&#x200A;&#x2014;&#x200A;&#x441;&#x43C;&#x43E;&#x442;&#x440;&#x438;&#x442;&#x435; &#x43B;&#x43E;&#x433;&#x438;, &#x432;&#x44B;&#x442;&#x430;&#x441;&#x43A;&#x438;&#x432;&#x430;&#x439;&#x442;&#x435; IP &#x438; &#x444;&#x438;&#x43B;&#x44C;&#x442;&#x440;&#x443;&#x439;&#x442;&#x435;.</p><p>L4&#x200A;&#x2014;&#x200A;tcpdump &#x43D;&#x430; &#x431;&#x430;&#x43B;&#x430;&#x43D;&#x441;&#x438;&#x440;&#x43E;&#x432;&#x449;&#x438;&#x43A;&#x435; (&#x43C;&#x430;&#x448;&#x438;&#x43D;&#x435; &#x433;&#x434;&#x435; &#x443; &#x432;&#x430;&#x441; &#x432;&#x438;&#x441;&#x438;&#x442; &#x43E;&#x441;&#x43D;&#x43E;&#x432;&#x43D;&#x43E;&#x439; IP) &#x438; &#x441;&#x43E;&#x441;&#x442;&#x430;&#x432;&#x43B;&#x44F;&#x439;&#x442;&#x435; &#x441;&#x43F;&#x438;&#x441;&#x43E;&#x43A; IP &#x438; &#x43F;&#x43E;&#x434;&#x441;&#x435;&#x442;&#x435;&#x439;. &#x41C;&#x43E;&#x436;&#x43D;&#x43E; &#x444;&#x438;&#x43B;&#x44C;&#x442;&#x440;&#x43E;&#x432;&#x430;&#x442;&#x44C; &#x438;&#x43B;&#x438; &#x43E;&#x442;&#x43F;&#x440;&#x430;&#x432;&#x438;&#x442;&#x44C; &#x445;&#x43E;&#x441;&#x442;&#x435;&#x440;&#x443;/&#x441;&#x435;&#x440;&#x432;&#x438;&#x441; &#x43F;&#x43E; &#x437;&#x430;&#x449;&#x438;&#x442;&#x435;.</p><p>&#x415;&#x441;&#x43B;&#x438; &#x432;&#x430;&#x43C; &#x437;&#x430;&#x431;&#x438;&#x43B;&#x438; &#x43A;&#x430;&#x43D;&#x430;&#x43B; &#x43C;&#x443;&#x441;&#x43E;&#x440;&#x43D;&#x44B;&#x43C; &#x442;&#x440;&#x430;&#x444;&#x438;&#x43A;&#x43E;&#x43C;, &#x442;&#x43E; &#x432;&#x430;&#x43C; &#x43F;&#x43E;&#x43C;&#x43E;&#x436;&#x435;&#x442; &#x438;&#x43B;&#x438; &#x432;&#x43D;&#x435;&#x448;&#x43D;&#x438;&#x439; &#x449;&#x438;&#x442; &#x438;&#x43B;&#x438; &#x445;&#x43E;&#x441;&#x442;&#x435;&#x440;, &#x434;&#x440;&#x443;&#x433;&#x438;&#x445; &#x432;&#x430;&#x440;&#x438;&#x430;&#x43D;&#x442;&#x43E;&#x432; &#x43F;&#x440;&#x43E;&#x441;&#x442;&#x43E; &#x43D;&#x435;&#x442;.</p><p>&#x41C;&#x43E;&#x436;&#x435;&#x442;&#x435; &#x43D;&#x430;&#x43F;&#x438;&#x441;&#x430;&#x442;&#x44C; &#x432; <a href="https://www.facebook.com/igkuznetsov" rel="noopener">FB</a>, &#x447;&#x435;&#x43C; &#x441;&#x43C;&#x43E;&#x433;&#x443; &#x43F;&#x43E;&#x43C;&#x43E;&#x433;&#x443;.</p><h4 id="--9">&#x415;&#x441;&#x43B;&#x438; &#x432;&#x44B; &#x441;&#x43C;&#x435;&#x43B;&#x44B;&#x439;, &#x43B;&#x43E;&#x432;&#x43A;&#x438;&#x439;, &#x443;&#x43C;&#x435;&#x43B;&#x44B;&#x439;&#x2026;</h4><p>&#x411;&#x43E;&#x442;&#x43D;&#x435;&#x442; &#x44D;&#x442;&#x43E; &#x43A;&#x443;&#x447;&#x430; &#x437;&#x430;&#x440;&#x430;&#x436;&#x435;&#x43D;&#x43D;&#x44B;&#x445; &#x43C;&#x430;&#x448;&#x438;&#x43D; (&#x43A;&#x430;&#x43C;&#x435;&#x440;&#x44B;, &#x440;&#x43E;&#x443;&#x442;&#x435;&#x440;&#x44B;, &#x432;&#x438;&#x440;&#x442;&#x443;&#x430;&#x43B;&#x44C;&#x43D;&#x44B;&#x435; &#x43C;&#x430;&#x448;&#x438;&#x43D;&#x44B; &#x441; WP, etc). &#x423; &#x43D;&#x435;&#x433;&#x43E; &#x435;&#x441;&#x442;&#x44C; 1-N &#x443;&#x43F;&#x440;&#x430;&#x432;&#x43B;&#x44F;&#x44E;&#x449;&#x438;&#x445; &#x446;&#x435;&#x43D;&#x442;&#x440;&#x43E;&#x432;. &#x417;&#x430; &#x446;&#x435;&#x43D;&#x442;&#x440;&#x430;&#x43C;&#x438; &#x43C;&#x43E;&#x433;&#x443;&#x442; &#x431;&#x44B;&#x442;&#x44C; &#x435;&#x449;&#x435; &#x446;&#x435;&#x43D;&#x442;&#x440;&#x44B; &#x438; &#x443;&#x436;&#x435; &#x437;&#x430; &#x43D;&#x438;&#x43C;&#x438; &#x447;&#x435;&#x43B;&#x43E;&#x432;&#x435;&#x43A; (&#x433;&#x440;&#x443;&#x43F;&#x43F;&#x430; &#x43B;&#x44E;&#x434;&#x435;&#x439;).</p><p>&#x427;&#x442;&#x43E;&#x431;&#x44B; &#x43E;&#x442;&#x431;&#x438;&#x442;&#x44C; &#x431;&#x43E;&#x442;&#x43D;&#x435;&#x442; &#x43D;&#x443;&#x436;&#x43D;&#x43E; &#x441;&#x43B;&#x43E;&#x43C;&#x430;&#x442;&#x44C; &#x43E;&#x434;&#x43D;&#x443; &#x438;&#x437; &#x437;&#x430;&#x440;&#x430;&#x436;&#x435;&#x43D;&#x43D;&#x44B;&#x445; &#x43C;&#x430;&#x448;&#x438;&#x43D;, &#x43E;&#x43F;&#x440;&#x435;&#x434;&#x435;&#x43B;&#x438;&#x442;&#x44C; &#x43E;&#x442;&#x43A;&#x443;&#x434;&#x430; &#x438;&#x434;&#x443;&#x442; &#x43A;&#x43E;&#x43C;&#x430;&#x43D;&#x434;&#x44B;, &#x441;&#x43B;&#x43E;&#x43C;&#x430;&#x442;&#x44C; &#x43E;&#x434;&#x43D;&#x443; &#x438;&#x437; &#x43C;&#x430;&#x448;&#x438;&#x43D; &#x443;&#x43F;&#x440;&#x430;&#x432;&#x43B;&#x44F;&#x44E;&#x449;&#x435;&#x433;&#x43E; &#x446;&#x435;&#x43D;&#x442;&#x440;&#x430;, &#x43F;&#x43E;&#x441;&#x43C;&#x43E;&#x442;&#x440;&#x435;&#x442;&#x44C; &#x43D;&#x435;&#x442; &#x43B;&#x438; &#x442;&#x430;&#x43C; &#x435;&#x449;&#x435; &#x43E;&#x434;&#x43D;&#x43E;&#x433;&#x43E; &#x441;&#x43B;&#x43E;&#x44F; &#x438; &#x442;&#x430;&#x43A; &#x432;&#x433;&#x43B;&#x443;&#x431;&#x44C;. &#x41A;&#x43E;&#x43D;&#x442;&#x440;&#x43E;&#x43B; &#x446;&#x435;&#x43D;&#x442;&#x440;&#x44B; &#x43C;&#x43E;&#x436;&#x43D;&#x43E; &#x43F;&#x440;&#x43E;&#x43B;&#x435;&#x447;&#x438;&#x442;&#x44C; &#x438; &#x43E;&#x441;&#x442;&#x430;&#x43D;&#x43E;&#x432;&#x438;&#x442;&#x44C; DDoS. TL; DR; &#x441;&#x442;&#x430;&#x442;&#x44C;&#x44F; &#x43E;&#x442; Wired &#x43E; &#x442;&#x43E;&#x43C;, &#x43A;&#x430;&#x43A; &#x43E;&#x442;&#x431;&#x438;&#x432;&#x430;&#x43B;&#x438; &#x43E;&#x434;&#x438;&#x43D; &#x438;&#x437; &#x441;&#x430;&#x43C;&#x44B;&#x445; &#x431;&#x43E;&#x43B;&#x44C;&#x448;&#x438;&#x445; <a href="https://www.wired.com/2017/03/russian-hacker-spy-botnet/?ref=igkuz.ru" rel="noopener">&#x431;&#x43E;&#x442;&#x43D;&#x435;&#x442;&#x43E;&#x432;</a>.</p><p>&#x412;&#x435;&#x441;&#x44C; &#x43F;&#x440;&#x435;&#x434;&#x44B;&#x434;&#x443;&#x449;&#x438;&#x439; &#x430;&#x431;&#x437;&#x430;&#x446; &#x44D;&#x442;&#x43E; &#x43D;&#x430;&#x440;&#x443;&#x448;&#x435;&#x43D;&#x438;&#x435; &#x437;&#x430;&#x43A;&#x43E;&#x43D;&#x43E;&#x434;&#x430;&#x442;&#x435;&#x43B;&#x44C;&#x441;&#x442;&#x432;&#x430;, &#x43A;&#x430;&#x43A; &#x43C;&#x438;&#x43D;&#x438;&#x43C;&#x443;&#x43C; &#x432; &#x420;&#x424;, &#x43F;&#x43E;&#x44D;&#x442;&#x43E;&#x43C;&#x443; &#x43F;&#x440;&#x435;&#x436;&#x434;&#x435; &#x447;&#x435;&#x43C; &#x442;&#x430;&#x43A; &#x434;&#x435;&#x43B;&#x430;&#x442;&#x44C;, &#x434;&#x430;&#x436;&#x435; &#x435;&#x441;&#x43B;&#x438; &#x432;&#x44B; &#x441;&#x43C;&#x43E;&#x436;&#x435;&#x442;&#x435;, &#x43F;&#x43E;&#x434;&#x443;&#x43C;&#x430;&#x439;&#x442;&#x435;.</p><p>&#x41C;&#x43D;&#x43E;&#x433;&#x438;&#x435; &#x438;&#x437;&#x434;&#x430;&#x43D;&#x438;&#x44F; &#x43F;&#x43E;&#x434;&#x432;&#x435;&#x440;&#x433;&#x430;&#x44E;&#x442;&#x441;&#x44F; DDoS &#x430;&#x442;&#x430;&#x43A;&#x430;&#x43C;. &#x41D;&#x430;&#x43F;&#x440;&#x438;&#x43C;&#x435;&#x440;, &#x432; &#x430;&#x43F;&#x440;&#x435;&#x43B;&#x435; &#x43D;&#x430;&#x43F;&#x430;&#x434;&#x430;&#x43B;&#x438; &#x43D;&#x430; <a href="https://medium.com/meduza-how-it-works/ddos-ab63424e595e?ref=igkuz.ru">&#x41C;&#x435;&#x434;&#x443;&#x437;&#x443;</a>. &#x42D;&#x442;&#x43E; &#x432;&#x441;&#x435;&#x433;&#x434;&#x430; &#x43D;&#x435;&#x43F;&#x440;&#x438;&#x44F;&#x442;&#x43D;&#x43E;, &#x437;&#x430;&#x442;&#x440;&#x430;&#x433;&#x438;&#x432;&#x430;&#x435;&#x442; &#x440;&#x430;&#x431;&#x43E;&#x442;&#x443; &#x432;&#x441;&#x435;&#x439; &#x43A;&#x43E;&#x43C;&#x430;&#x43D;&#x434;&#x44B; &#x438; &#x431;&#x438;&#x437;&#x43D;&#x435;&#x441;&#x430; &#x432; &#x446;&#x435;&#x43B;&#x43E;&#x43C; &#x438; &#x432;&#x430;&#x43C; &#x43D;&#x443;&#x436;&#x43D;&#x43E; &#x431;&#x44B;&#x442;&#x44C; &#x433;&#x43E;&#x442;&#x43E;&#x432;&#x44B;&#x43C; &#x43A; &#x44D;&#x442;&#x43E;&#x43C;&#x443;.</p>]]></content:encoded></item><item><title><![CDATA[Парсим  Google Analytics на GO #1]]></title><description><![CDATA[Авторизация c OAuth2 в Google Analytics на GO]]></description><link>https://igkuz.ru/parsim-google-analytics-na-go/</link><guid isPermaLink="false">5e9209026d9007355d8bde59</guid><category><![CDATA[программирование]]></category><category><![CDATA[GO]]></category><dc:creator><![CDATA[Igor Kuznetsov]]></dc:creator><pubDate>Sun, 29 May 2016 19:22:20 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>GO &#x44D;&#x442;&#x43E; &#x443;&#x436;&#x435; &#x434;&#x430;&#x436;&#x435; &#x43D;&#x435; &quot;&#x441;&#x442;&#x438;&#x43B;&#x44C;&#x43D;&#x43E; &#x43C;&#x43E;&#x434;&#x43D;&#x43E; &#x43C;&#x43E;&#x43B;&#x43E;&#x434;&#x435;&#x436;&#x43D;&#x43E;&quot;, &#x430; &#x43F;&#x440;&#x43E;&#x441;&#x442;&#x43E; &#x43D;&#x43E;&#x440;&#x43C;&#x430;. &#x41E;&#x43D; &#x43F;&#x43E;&#x441;&#x442;&#x435;&#x43F;&#x435;&#x43D;&#x43D;&#x43E; &#x441;&#x442;&#x430;&#x43D;&#x43E;&#x432;&#x438;&#x442;&#x441;&#x44F; &#x441;&#x442;&#x430;&#x43D;&#x434;&#x430;&#x440;&#x442;&#x43E;&#x43C; &#x434;&#x43B;&#x44F; &#x43D;&#x430;&#x43F;&#x438;&#x441;&#x430;&#x43D;&#x438;&#x44F; &#x434;&#x435;&#x43C;&#x43E;&#x43D;&#x43E;&#x432; &#x438; &#x434;&#x440;&#x443;&#x433;&#x438;&#x445; &#x43C;&#x435;&#x43B;&#x43A;&#x438;&#x445; &#x438; &#x431;&#x43E;&#x43B;&#x44C;&#x448;&#x438;&#x445; &#x441;&#x438;&#x441;&#x442;&#x435;&#x43C;&#x43D;&#x44B;&#x445; &#x443;&#x442;&#x438;&#x43B;&#x438;&#x442;. &#x41D;&#x430; &#x43D;&#x435;&#x43C; &#x43F;&#x438;&#x448;&#x443;&#x442; &#x430;&#x43F;&#x438;, &#x43A;&#x43E;&#x442;&#x43E;&#x440;&#x44B;&#x435; &#x43E;&#x431;&#x440;&#x430;&#x431;&#x430;&#x442;&#x44B;&#x432;&#x430;&#x44E;&#x442; &#x43A;&#x443;&#x447;&#x443; &#x437;&#x430;&#x43F;&#x440;&#x43E;&#x441;&#x43E;&#x432; &#x438; &#x43C;&#x43D;&#x43E;&#x433;&#x43E;&#x435; &#x434;&#x440;&#x443;&#x433;&#x43E;&#x435;.</p>
<p>&#x421;&#x441;&#x44B;&#x43B;&#x43A;&#x438; &#x43D;&#x430; &#x431;&#x430;&#x437;&#x43E;&#x432;&#x44B;&#x435; &#x442;&#x443;&#x442;&#x43E;&#x440;&#x438;&#x430;&#x43B;&#x44B; &#x438; &#x434;&#x440;&#x443;&#x433;&#x438;&#x435; &#x43A;&#x43B;&#x430;&#x441;&#x441;&#x43D;&#x44B;&#x435; &#x441;&#x442;&#x430;&#x442;&#x44C;&#x438; &quot;&#x43A;&#x430;&#x43A; &#x43D;&#x430;&#x447;&#x430;&#x442;&#x44C; &#x43F;&#x438;&#x441;&#x430;&#x442;&#x44C;&quot; &#x43F;&#x440;&#x43E;&#x449;&#x435; &#x43D;&#x430;&#x439;&#x442;&#x438; &#x432; &#x433;&#x443;&#x433;&#x43B;&#x435;. &#x417;&#x434;&#x435;&#x441;&#x44C; &#x436;&#x435; &#x43E;&#x43F;&#x438;&#x448;&#x443; &#x437;&#x430;&#x434;&#x430;&#x447;&#x443; &#x438; &#x440;&#x435;&#x448;&#x435;&#x43D;&#x438;&#x435;.</p>
<h3 id>&#x417;&#x430;&#x434;&#x430;&#x447;&#x430;</h3>
<p>&#x41D;&#x430;&#x43F;&#x438;&#x441;&#x430;&#x442;&#x44C; &#x43F;&#x430;&#x440;&#x441;&#x435;&#x440; &#x434;&#x430;&#x43D;&#x43D;&#x44B;&#x445; &#x438;&#x437; Google Analytics. &#x412; &#x43F;&#x435;&#x440;&#x432;&#x43E;&#x43C; &#x43F;&#x440;&#x438;&#x431;&#x43B;&#x438;&#x436;&#x435;&#x43D;&#x438;&#x438; &#x432;&#x44B;&#x442;&#x430;&#x449;&#x438;&#x442;&#x44C; &#x442;&#x43E;&#x43B;&#x44C;&#x43A;&#x43E; &#x43F;&#x440;&#x43E;&#x441;&#x43C;&#x43E;&#x442;&#x440;&#x44B; (pageViews) &#x443; &#x437;&#x430;&#x434;&#x430;&#x43D;&#x43D;&#x43E;&#x433;&#x43E; &#x43C;&#x430;&#x441;&#x441;&#x438;&#x432;&#x430; &#x441;&#x441;&#x44B;&#x43B;&#x43E;&#x43A;.</p>
<h3 id>&#x41F;&#x440;&#x43E;&#x442;&#x43E;&#x442;&#x438;&#x43F;</h3>
<ol>
<li>&#x410;&#x432;&#x442;&#x43E;&#x440;&#x438;&#x437;&#x443;&#x435;&#x43C;&#x441;&#x44F; &#x447;&#x435;&#x440;&#x435;&#x437; OAuth2 &#x432; Google</li>
<li>&#x417;&#x430;&#x43F;&#x440;&#x430;&#x448;&#x438;&#x432;&#x430;&#x435;&#x43C; &#x441;&#x43F;&#x438;&#x441;&#x43E;&#x43A; &#x434;&#x43E;&#x441;&#x442;&#x443;&#x43F;&#x43D;&#x44B;&#x445; View &#x438;&#x437; &#x430;&#x43D;&#x430;&#x43B;&#x438;&#x442;&#x438;&#x43A;&#x438;</li>
<li>&#x412;&#x44B;&#x431;&#x438;&#x440;&#x430;&#x435;&#x43C; &#x43D;&#x443;&#x436;&#x43D;&#x44B;&#x439; View</li>
<li>&#x41F;&#x43E;&#x43B;&#x443;&#x447;&#x430;&#x435;&#x43C; &#x43E;&#x442; &#x43F;&#x43E;&#x43B;&#x44C;&#x437;&#x43E;&#x432;&#x430;&#x442;&#x435;&#x43B;&#x44F; &#x441;&#x43F;&#x438;&#x441;&#x43E;&#x43A; &#x441;&#x441;&#x44B;&#x43B;&#x43E;&#x43A; &#x438; &#x434;&#x430;&#x442;&#x44B; &#x43D;&#x430;&#x447;&#x430;&#x43B;&#x430; &#x438; &#x43A;&#x43E;&#x43D;&#x446;&#x430; &#x43F;&#x43E;&#x438;&#x441;&#x43A;&#x430;</li>
</ol>
<h3 id>&#x41F;&#x440;&#x43E;&#x431;&#x43B;&#x435;&#x43C;&#x44B; &#x43F;&#x43E; &#x43F;&#x443;&#x442;&#x438;</h3>
<ul>
<li>&#x41D;&#x438;&#x43A;&#x43E;&#x433;&#x434;&#x430; &#x43D;&#x438;&#x447;&#x435;&#x433;&#x43E; &#x43D;&#x435; &#x43F;&#x438;&#x441;&#x430;&#x43B; &#x43D;&#x430; GO</li>
<li>&#x423;&#x440;&#x43E;&#x434;&#x43B;&#x438;&#x432;&#x430;&#x44F; &#x434;&#x43E;&#x43A;&#x443;&#x43C;&#x435;&#x43D;&#x442;&#x430;&#x446;&#x438;&#x44F; Google Analytics</li>
<li>&#x411;&#x438;&#x431;&#x43B;&#x438;&#x43E;&#x442;&#x435;&#x43A;&#x438; &#x43E;&#x442; Google &#x431;&#x435;&#x437; &#x43D;&#x43E;&#x440;&#x43C;&#x430;&#x43B;&#x44C;&#x43D;&#x44B;&#x445; &#x43F;&#x440;&#x438;&#x43C;&#x435;&#x440;&#x43E;&#x432; &#x438;&#x441;&#x43F;&#x43E;&#x43B;&#x44C;&#x437;&#x43E;&#x432;&#x430;&#x43D;&#x438;&#x44F;</li>
</ul>
<p>&#x421;&#x440;&#x430;&#x437;&#x443; &#x43F;&#x440;&#x435;&#x434;&#x443;&#x43F;&#x440;&#x435;&#x436;&#x434;&#x430;&#x44E;, &#x43A;&#x43E;&#x434; &#x43D;&#x435; &#x43F;&#x440;&#x435;&#x442;&#x435;&#x43D;&#x434;&#x443;&#x435;&#x442; &#x43D;&#x430; &#x43A;&#x440;&#x430;&#x441;&#x43E;&#x442;&#x443; &#x438; &#x433;&#x435;&#x43D;&#x438;&#x430;&#x43B;&#x44C;&#x43D;&#x43E;&#x441;&#x442;&#x44C;, &#x44D;&#x442;&#x43E; &#x43F;&#x440;&#x43E;&#x441;&#x442;&#x43E; &#x43F;&#x440;&#x43E;&#x431;&#x43D;&#x44B;&#x439; &#x437;&#x430;&#x445;&#x43E;&#x434;, &#x43D;&#x430;&#x43A;&#x438;&#x434;&#x430;&#x43D;&#x43D;&#x44B;&#x439; &#x437;&#x430; &#x43F;&#x430;&#x440;&#x443; &#x432;&#x435;&#x447;&#x435;&#x440;&#x43E;&#x432;.</p>
<h3 id>&#x41D;&#x430;&#x447;&#x430;&#x43B;&#x43E;</h3>
<p>&#x423;&#x441;&#x442;&#x430;&#x43D;&#x43E;&#x432;&#x438;&#x442;&#x44C; GO. &#x421;&#x442;&#x430;&#x432;&#x438;&#x43B; &#x447;&#x435;&#x440;&#x435;&#x437; Homebrew &#x432;&#x435;&#x440;&#x441;&#x438;&#x44E; 1.6.2 &#x2013; &#x43F;&#x43E;&#x441;&#x43B;&#x435;&#x434;&#x43D;&#x44F;&#x44F; &#x434;&#x43E;&#x441;&#x442;&#x443;&#x43F;&#x43D;&#x430;&#x44F; &#x43D;&#x430; &#x43C;&#x43E;&#x43C;&#x435;&#x43D;&#x442; &#x43D;&#x430;&#x43F;&#x438;&#x441;&#x430;&#x43D;&#x438;&#x44F; &#x441;&#x442;&#x430;&#x442;&#x44C;&#x438;.</p>
<p>&#x414;&#x430;&#x43B;&#x435;&#x435; &#x43D;&#x443;&#x436;&#x43D;&#x43E; &#x441;&#x43E;&#x437;&#x434;&#x430;&#x442;&#x44C; &#x43F;&#x440;&#x438;&#x43B;&#x43E;&#x436;&#x435;&#x43D;&#x438;&#x435; &#x432; <a href="https://console.developers.google.com/?ref=igkuz.ru">Google Developers Console</a>. &#x412;&#x43A;&#x43B;&#x44E;&#x447;&#x438;&#x442;&#x44C; &#x434;&#x43B;&#x44F; &#x43D;&#x435;&#x433;&#x43E; <strong>Analytics API</strong> &#x438; <strong>Analytics Reporting API V4</strong>. &#x414;&#x43B;&#x44F; &#x442;&#x435;&#x441;&#x442;&#x43E;&#x432; callback url &#x43C;&#x43E;&#x436;&#x43D;&#x43E; &#x443;&#x43A;&#x430;&#x437;&#x430;&#x442;&#x44C; &#x43D;&#x430; localhost. &#x423; &#x43C;&#x435;&#x43D;&#x44F; &#x431;&#x44B;&#x43B;&#x43E; &#x443;&#x43A;&#x430;&#x437;&#x430;&#x43D;&#x43E; localhost:3000.</p>
<p><img src="https://igkuz.ru/content/images/2016/05/GoogleDevelopersConsole.png" alt loading="lazy"></p>
<p>&#x421;&#x43E;&#x445;&#x440;&#x430;&#x43D;&#x438;&#x442;&#x44C; &#x43A;&#x443;&#x434;&#x430;-&#x442;&#x43E; <strong>ClientID</strong> &#x438; <strong>ClientSecret</strong>. &#x418;&#x445; &#x43C;&#x43E;&#x436;&#x43D;&#x43E; &#x43D;&#x430;&#x439;&#x442;&#x438; &#x432; &#x443;&#x447;&#x435;&#x442;&#x43D;&#x44B;&#x445; &#x434;&#x430;&#x43D;&#x43D;&#x44B;&#x445; &#x432;&#x43E; &#x432;&#x43A;&#x43B;&#x430;&#x434;&#x43A;&#x435; &#x441;&#x43B;&#x435;&#x432;&#x430;.</p>
<p><img src="https://igkuz.ru/content/images/2016/05/ClientCredentials.png" alt loading="lazy"></p>
<p>&#x41F;&#x43E;&#x434;&#x433;&#x43E;&#x442;&#x43E;&#x432;&#x438;&#x442;&#x435;&#x43B;&#x44C;&#x43D;&#x44B;&#x435; &#x434;&#x435;&#x439;&#x441;&#x442;&#x432;&#x438;&#x44F; &#x437;&#x430;&#x43A;&#x43E;&#x43D;&#x447;&#x435;&#x43D;&#x44B;, &#x43C;&#x43E;&#x436;&#x43D;&#x43E; &#x43F;&#x440;&#x438;&#x441;&#x442;&#x443;&#x43F;&#x430;&#x442;&#x44C; &#x43A; &#x43D;&#x430;&#x43F;&#x438;&#x441;&#x430;&#x43D;&#x438;&#x44E; &#x43A;&#x43E;&#x434;&#x430;.</p>
<p>&#x414;&#x43B;&#x44F; &#x430;&#x432;&#x442;&#x43E;&#x440;&#x438;&#x437;&#x430;&#x446;&#x438;&#x438; &#x43D;&#x430;&#x434;&#x43E; &#x43F;&#x43E;&#x434;&#x43D;&#x44F;&#x442;&#x44C; &#x43F;&#x440;&#x43E;&#x441;&#x442;&#x435;&#x43D;&#x44C;&#x43A;&#x438;&#x439; http &#x441;&#x435;&#x440;&#x432;&#x435;&#x440; &#x438; &#x441;&#x434;&#x435;&#x43B;&#x430;&#x442;&#x44C; &#x43D;&#x435;&#x441;&#x43A;&#x43E;&#x43B;&#x44C;&#x43A;&#x43E; &#x441;&#x442;&#x440;&#x430;&#x43D;&#x438;&#x446;. &#x41D;&#x430;&#x447;&#x430;&#x442;&#x44C; &#x43C;&#x43E;&#x436;&#x43D;&#x43E; &#x441;&#x43E; &#x441;&#x442;&#x430;&#x442;&#x44C;&#x438; &#x43D;&#x430; golang.org &#x2013; <a href="https://golang.org/doc/articles/wiki/?ref=igkuz.ru">Writing Web Applications</a>. &#x41F;&#x440;&#x438;&#x44F;&#x442;&#x43D;&#x43E; &#x443;&#x434;&#x438;&#x432;&#x438;&#x43B;&#x430; &#x43E;&#x431;&#x448;&#x438;&#x440;&#x43D;&#x43E;&#x441;&#x442;&#x44C; &#x444;&#x443;&#x43D;&#x43A;&#x446;&#x438;&#x43E;&#x43D;&#x430;&#x43B;&#x430; &#x432; &#x441;&#x442;&#x430;&#x43D;&#x434;&#x430;&#x440;&#x442;&#x43D;&#x44B;&#x445; &#x43F;&#x430;&#x43A;&#x435;&#x442;&#x430;&#x445;. &#x414;&#x43B;&#x44F; &#x431;&#x43E;&#x43B;&#x44C;&#x448;&#x438;&#x43D;&#x441;&#x442;&#x432;&#x430; &#x437;&#x430;&#x434;&#x430;&#x447; &#x43C;&#x43E;&#x436;&#x43D;&#x43E; &#x43D;&#x435; &#x438;&#x43C;&#x43F;&#x43E;&#x440;&#x442;&#x438;&#x440;&#x43E;&#x432;&#x430;&#x442;&#x44C; &#x441;&#x442;&#x43E;&#x440;&#x43E;&#x43D;&#x43D;&#x438;&#x435; &#x431;&#x438;&#x431;&#x43B;&#x438;&#x43E;&#x442;&#x435;&#x43A;&#x438;, &#x430; &#x438;&#x441;&#x43F;&#x43E;&#x43B;&#x44C;&#x437;&#x43E;&#x432;&#x430;&#x442;&#x44C; &#x442;&#x43E;&#x43B;&#x44C;&#x43A;&#x43E; &#x431;&#x430;&#x437;&#x43E;&#x432;&#x44B;&#x435; &#x43F;&#x430;&#x43A;&#x435;&#x442;&#x44B; &#x438; &#x443;&#x442;&#x438;&#x43B;&#x438;&#x442;&#x44B; &#x432; &#x43A;&#x43E;&#x43C;&#x43F;&#x43B;&#x435;&#x43A;&#x442;&#x435; &#x441; &#x44F;&#x437;&#x44B;&#x43A;&#x43E;&#x43C;.</p>
<p>&#x41E;&#x442;&#x434;&#x435;&#x43B;&#x44C;&#x43D;&#x430;&#x44F; &#x431;&#x43E;&#x43B;&#x44C; &#x2013; &#x43F;&#x430;&#x43A;&#x435;&#x442;&#x43D;&#x44B;&#x439; &#x43C;&#x435;&#x43D;&#x435;&#x434;&#x436;&#x435;&#x440;. &#x415;&#x433;&#x43E; &#x43F;&#x440;&#x43E;&#x441;&#x442;&#x43E; &#x43D;&#x435;&#x442;. &#x41D;&#x430; Github &#x43C;&#x43E;&#x436;&#x43D;&#x43E; &#x43D;&#x430;&#x439;&#x442;&#x438; &#x441;&#x43F;&#x438;&#x441;&#x43E;&#x43A; &#x43F;&#x430;&#x43A;&#x435;&#x442;&#x43D;&#x44B;&#x445; &#x43C;&#x435;&#x43D;&#x435;&#x434;&#x436;&#x435;&#x440;&#x43E;&#x432; &#x441;&#x442;&#x43E;&#x440;&#x43E;&#x43D;&#x43D;&#x438;&#x445; &#x440;&#x430;&#x437;&#x440;&#x430;&#x431;&#x43E;&#x442;&#x447;&#x438;&#x43A;&#x43E;&#x432; &#x438; &#x432;&#x44B;&#x431;&#x440;&#x430;&#x442;&#x44C; &#x43D;&#x430; &#x441;&#x432;&#x43E;&#x439; &#x432;&#x43A;&#x443;&#x441;. &#x412; &#x441;&#x442;&#x430;&#x442;&#x44C;&#x435; &#x43D;&#x435; &#x431;&#x443;&#x434;&#x443; &#x43F;&#x43E;&#x434;&#x440;&#x43E;&#x431;&#x43D;&#x43E; &#x43D;&#x430; &#x43D;&#x435;&#x43C; &#x43E;&#x441;&#x442;&#x430;&#x43D;&#x430;&#x432;&#x43B;&#x438;&#x432;&#x430;&#x442;&#x44C;&#x441;&#x44F;, &#x43F;&#x43E;&#x442;&#x43E;&#x43C;&#x443; &#x447;&#x442;&#x43E; &#x43D;&#x435; &#x438;&#x441;&#x43F;&#x43E;&#x43B;&#x44C;&#x437;&#x43E;&#x432;&#x430;&#x43B; &#x438; &#x43D;&#x435; &#x43C;&#x43E;&#x433;&#x443; &#x442;&#x43E;&#x43B;&#x43A;&#x43E;&#x43C; &#x441;&#x43A;&#x430;&#x437;&#x430;&#x442;&#x44C; &#x43A;&#x430;&#x43A;&#x438;&#x435; &#x43F;&#x43B;&#x44E;&#x441;&#x44B; &#x438; &#x43C;&#x438;&#x43D;&#x443;&#x441;&#x44B; &#x443; &#x43A;&#x430;&#x436;&#x434;&#x43E;&#x433;&#x43E;. &#x421; &#x43A;&#x435;&#x43C; &#x44F; &#x43E;&#x431;&#x449;&#x430;&#x43B;&#x441;&#x44F; &#x2013; &#x441;&#x43E;&#x432;&#x435;&#x442;&#x443;&#x44E;&#x442; gvt.</p>
<p>&#x41A; &#x43A;&#x43E;&#x434;&#x443;. &#x41F;&#x440;&#x43E;&#x441;&#x442;&#x43E;&#x439; http &#x441;&#x435;&#x440;&#x432;&#x435;&#x440;:</p>
<pre><code class="language-go">package main

import (
  &quot;net/http&quot;
)

func indexHandler(w http.ResponseWriter, r *http.Request) {
  fmt.Frintf(w, &quot;Hello from Index&quot;)
}

func main() {
  http.HandleFunc(&quot;/&quot;, indexHandler)
  http.HandleAndServe(&quot;:3000&quot;, nil)
}
</code></pre>
<p>&#x421;&#x43B;&#x443;&#x448;&#x430;&#x435;&#x43C; &#x43F;&#x43E;&#x440;&#x442; 3000 &#x438; &#x43F;&#x43E; &#x430;&#x434;&#x440;&#x435;&#x441;&#x443; <a href="http://localhost:3000/?ref=igkuz.ru">http://localhost:3000/</a> &#x2013; &#x43E;&#x442;&#x434;&#x430;&#x435;&#x43C;  &#x442;&#x435;&#x43A;&#x441;&#x442;&#x43E;&#x43C; <code>Hello from Index</code>.</p>
<p>&#x414;&#x43B;&#x44F; OAuth 2.0 &#x43D;&#x430;&#x43C; &#x43D;&#x443;&#x436;&#x43D;&#x43E; &#x441;&#x434;&#x435;&#x43B;&#x430;&#x442;&#x44C; &#x440;&#x435;&#x434;&#x438;&#x440;&#x435;&#x43A;&#x442; &#x43D;&#x430; &#x441;&#x442;&#x440;&#x430;&#x43D;&#x438;&#x446;&#x443; &#x432; Google API, &#x447;&#x442;&#x43E;&#x431;&#x44B; &#x43F;&#x43E;&#x43B;&#x44C;&#x437;&#x43E;&#x432;&#x430;&#x442;&#x435;&#x43B;&#x44C; &#x440;&#x430;&#x437;&#x440;&#x435;&#x448;&#x438;&#x43B; &#x43F;&#x440;&#x438;&#x43B;&#x43E;&#x436;&#x435;&#x43D;&#x438;&#x44E; &#x434;&#x435;&#x43B;&#x430;&#x442;&#x44C; &#x440;&#x430;&#x437;&#x43D;&#x44B;&#x435; &#x43C;&#x430;&#x43D;&#x438;&#x43F;&#x443;&#x43B;&#x44F;&#x446;&#x438;&#x438; &#x441; &#x434;&#x430;&#x43D;&#x43D;&#x44B;&#x43C;&#x438; &#x438; &#x43F;&#x43E;&#x43B;&#x443;&#x447;&#x438;&#x442;&#x44C; &#x43E;&#x431;&#x440;&#x430;&#x442;&#x43D;&#x43E; &#x432; &#x437;&#x430;&#x43F;&#x440;&#x43E;&#x441;&#x435; access_token, &#x43A;&#x43E;&#x442;&#x43E;&#x440;&#x44B;&#x439; &#x431;&#x443;&#x434;&#x435;&#x43C; &#x438;&#x441;&#x43F;&#x43E;&#x43B;&#x44C;&#x437;&#x43E;&#x432;&#x430;&#x442;&#x44C; &#x432; &#x437;&#x430;&#x43F;&#x440;&#x43E;&#x441;&#x430;&#x445; &#x43A; API.</p>
<pre><code class="language-go">func authHandler(w http.ResponseWriter, r *http.Request) {
}

func authHandler(w http.ResponseWriter, r *http.Request) {
}

func main() {
  http.HandleFunc(&quot;/authorize&quot;, authHandler)
  http.HandleFunc(&quot;/connect&quot;, connectHandler)

  http.HandleFunc(&quot;/&quot;, indexHandler)
  http.HandleAndServe(&quot;:3000&quot;, nil)
}
</code></pre>
<p>&#x41D;&#x430; &#x433;&#x43B;&#x430;&#x432;&#x43D;&#x43E;&#x439; &#x441;&#x442;&#x440;&#x430;&#x43D;&#x438;&#x446;&#x435; &#x432;&#x44B;&#x432;&#x435;&#x434;&#x435;&#x43C; &#x441;&#x441;&#x44B;&#x43B;&#x43A;&#x443; &#x43D;&#x430; <strong>/authorize</strong>, &#x43E;&#x442;&#x43A;&#x443;&#x434;&#x430; &#x441;&#x434;&#x435;&#x43B;&#x430;&#x435;&#x43C; &#x440;&#x435;&#x434;&#x438;&#x440;&#x435;&#x43A;&#x442; &#x432; Google, &#x447;&#x442;&#x43E;&#x431;&#x44B; &#x43F;&#x43E;&#x43B;&#x44C;&#x437;&#x43E;&#x432;&#x430;&#x442;&#x435;&#x43B;&#x44C; &#x432;&#x44B;&#x434;&#x430;&#x43B; &#x43D;&#x430;&#x43C; &#x43F;&#x440;&#x430;&#x432;&#x430;. &#x41D;&#x430; <strong>/connect</strong> &#x431;&#x443;&#x434;&#x435;&#x43C; &#x436;&#x434;&#x430;&#x442;&#x44C; &#x43E;&#x442;&#x432;&#x435;&#x442;&#x430; &#x43E;&#x442; Google &#x441; &#x43A;&#x43E;&#x434;&#x43E;&#x43C; &#x430;&#x432;&#x442;&#x43E;&#x440;&#x438;&#x437;&#x430;&#x446;&#x438;&#x438;, &#x43F;&#x43E; &#x43A;&#x43E;&#x442;&#x43E;&#x440;&#x43E;&#x43C;&#x443; &#x43F;&#x43E;&#x43B;&#x443;&#x447;&#x438;&#x43C; <strong>access_token</strong>.</p>
<p>&#x41F;&#x43E;&#x441;&#x43B;&#x435; &#x43F;&#x43E;&#x43B;&#x443;&#x447;&#x435;&#x43D;&#x438;&#x44F; &#x442;&#x43E;&#x43A;&#x435;&#x43D;&#x430; &#x43D;&#x443;&#x436;&#x43D;&#x43E; &#x435;&#x433;&#x43E; &#x43A;&#x443;&#x434;&#x430;-&#x442;&#x43E; &#x441;&#x43E;&#x445;&#x440;&#x430;&#x43D;&#x438;&#x442;&#x44C;, &#x434;&#x43B;&#x44F; &#x44D;&#x442;&#x43E;&#x433;&#x43E; &#x432;&#x43F;&#x43E;&#x43B;&#x43D;&#x435; &#x441;&#x43E;&#x439;&#x434;&#x435;&#x442; &#x441;&#x435;&#x441;&#x441;&#x438;&#x44F;. &#x412; production &#x442;&#x430;&#x43A;&#x43E;&#x435; &#x434;&#x435;&#x43B;&#x430;&#x442;&#x44C; &#x43D;&#x435; &#x441;&#x442;&#x43E;&#x438;&#x442; &#x438; &#x43D;&#x430;&#x434;&#x43E; &#x438;&#x441;&#x43F;&#x43E;&#x43B;&#x44C;&#x437;&#x43E;&#x432;&#x430;&#x442;&#x44C; &#x431;&#x430;&#x437;&#x443;, &#x43D;&#x43E; &#x44F; &#x43D;&#x430;&#x43A;&#x438;&#x434;&#x44B;&#x432;&#x430;&#x43B; &#x43F;&#x440;&#x43E;&#x442;&#x43E;&#x442;&#x438;&#x43F;, &#x43F;&#x43E;&#x44D;&#x442;&#x43E;&#x43C;&#x443; &#x441;&#x435;&#x441;&#x441;&#x438;&#x438; &#x43F;&#x43E;&#x434;&#x43E;&#x439;&#x434;&#x443;&#x442;.</p>
<p>&#x414;&#x43B;&#x44F; &#x440;&#x430;&#x431;&#x43E;&#x442;&#x44B; &#x441; &#x442;&#x43E;&#x43A;&#x435;&#x43D;&#x43E;&#x43C; &#x431;&#x443;&#x434;&#x435;&#x43C; &#x43F;&#x43E;&#x43B;&#x44C;&#x437;&#x43E;&#x432;&#x430;&#x442;&#x44C;&#x441;&#x44F; &#x431;&#x438;&#x431;&#x43B;&#x438;&#x43E;&#x442;&#x435;&#x43A;&#x43E;&#x439; &#x43E;&#x442; Google <a href="https://github.com/golang/oauth2?ref=igkuz.ru">oauth2</a>, &#x430; &#x434;&#x43B;&#x44F; &#x440;&#x430;&#x431;&#x43E;&#x442;&#x44B; &#x441; &#x441;&#x435;&#x441;&#x441;&#x438;&#x44F;&#x43C;&#x438; &#x431;&#x438;&#x431;&#x43B;&#x438;&#x43E;&#x442;&#x435;&#x43A;&#x43E;&#x439; <a href="https://github.com/gorilla/sessions?ref=igkuz.ru">sessions</a> &#x438;&#x437; GorillaToolkit.</p>
<p>&#x41D;&#x430;&#x43F;&#x43E;&#x43C;&#x43D;&#x44E;, &#x447;&#x442;&#x43E; &#x432; &#x44D;&#x442;&#x43E;&#x439; &#x441;&#x442;&#x430;&#x442;&#x44C;&#x435; &#x43D;&#x435; &#x43E;&#x43F;&#x438;&#x441;&#x430;&#x43D;&#x430; &#x43D;&#x430;&#x447;&#x430;&#x43B;&#x44C;&#x43D;&#x430;&#x44F; &#x43D;&#x430;&#x441;&#x442;&#x440;&#x43E;&#x439;&#x43A;&#x430; &#x43E;&#x43A;&#x440;&#x443;&#x436;&#x435;&#x43D;&#x438;&#x44F; GO, &#x43F;&#x440;&#x435;&#x434;&#x43F;&#x43E;&#x43B;&#x430;&#x433;&#x430;&#x44E;, &#x447;&#x442;&#x43E; &#x441; &#x44D;&#x442;&#x438;&#x43C; &#x43C;&#x43E;&#x436;&#x43D;&#x43E; &#x441;&#x43F;&#x440;&#x430;&#x432;&#x438;&#x442;&#x44C;&#x441;&#x44F; &#x441;&#x430;&#x43C;&#x43E;&#x441;&#x442;&#x43E;&#x44F;&#x442;&#x435;&#x43B;&#x44C;&#x43D;&#x43E; &#x43F;&#x43E;&#x441;&#x43B;&#x435; &#x43F;&#x440;&#x43E;&#x447;&#x442;&#x435;&#x43D;&#x438;&#x44F; &#x43D;&#x435;&#x441;&#x43A;&#x43E;&#x43B;&#x44C;&#x43A;&#x438;&#x445; &#x441;&#x442;&#x430;&#x442;&#x435;&#x439;. &#x41F;&#x43E;&#x44D;&#x442;&#x43E;&#x43C;&#x443; &#x443;&#x43A;&#x430;&#x447;&#x438;&#x432;&#x430;&#x435;&#x43C; &#x431;&#x438;&#x431;&#x43B;&#x438;&#x43E;&#x442;&#x435;&#x43A;&#x438; &#x441;&#x435;&#x431;&#x435; &#x432; workspace &#x441; &#x43F;&#x43E;&#x43C;&#x43E;&#x449;&#x44C;&#x44E; &#x43A;&#x43E;&#x43C;&#x430;&#x43D;&#x434;:</p>
<pre><code class="language-bash">go get github.com/gorilla/sessions
go get golang.org/x/oauth2
</code></pre>
<p>&#x418;&#x43C;&#x43F;&#x43E;&#x440;&#x442;&#x438;&#x440;&#x443;&#x435;&#x43C; &#x438;&#x445; &#x432; &#x43F;&#x440;&#x43E;&#x435;&#x43A;&#x442;&#x435;.</p>
<pre><code class="language-go">import(
  &quot;net/http&quot;
  &quot;github.com/gorilla/sessions&quot;
  &quot;golang.rog/x/oauth2&quot;
  &quot;golang.rog/x/oauth2/google&quot;
)

...
</code></pre>
<p>&#x412; &#x431;&#x438;&#x431;&#x43B;&#x438;&#x43E;&#x442;&#x435;&#x43A;&#x430;&#x445; &#x435;&#x441;&#x442;&#x44C; &#x43C;&#x435;&#x442;&#x43E;&#x434;&#x44B; &#x434;&#x43B;&#x44F; &#x43F;&#x43E;&#x43B;&#x443;&#x447;&#x435;&#x43D;&#x438;&#x44F; &#x43A;&#x43E;&#x43D;&#x444;&#x438;&#x433;&#x430; &#x438;&#x437; json &#x444;&#x430;&#x439;&#x43B;&#x430;, &#x43D;&#x43E; &#x434;&#x43B;&#x44F; &#x43F;&#x440;&#x43E;&#x442;&#x43E;&#x442;&#x438;&#x43F;&#x430; &#x43C;&#x43E;&#x436;&#x43D;&#x43E; &#x437;&#x430;&#x431;&#x438;&#x442;&#x44C; &#x44D;&#x442;&#x43E; &#x432;&#x441;&#x435; &#x440;&#x443;&#x43A;&#x430;&#x43C;&#x438;.</p>
<pre><code class="language-go">import(
 ...
)

const (
  clientID        = &quot;your_client_id&quot;
  clientSecret    = &quot;your_client_secret&quot;
  applicationName = &quot;your_application_name&quot;
)

var store = sessions.NewCookieStore([]byte(&quot;gaIntegrationStore&quot;))

var config = &amp;oauth2.Config{
  ClientID: clientID,
  ClientSecret: clientSecret,
  Scopes: []string{&quot;https://www.googleapis.com/auth/analytics&quot;, &quot;https://www.googleapis.com/auth/analytics.readonly&quot;},
  Endpoint: google.Endpoint,
  RedirectUrl: &quot;http://localhost:3000/connect&quot;,
}
</code></pre>
<p>oauth2 &#x2013; &#x44D;&#x442;&#x43E; &#x43D;&#x430;&#x431;&#x43E;&#x440; &#x43C;&#x435;&#x442;&#x43E;&#x434;&#x43E;&#x432; &#x434;&#x43B;&#x44F; &#x440;&#x430;&#x431;&#x43E;&#x442;&#x44B; &#x441; OAuth 2.0 &#x430;&#x432;&#x442;&#x43E;&#x440;&#x438;&#x437;&#x430;&#x446;&#x438;&#x435;&#x439;, &#x430; &#x432; &#x43F;&#x430;&#x43F;&#x43A;&#x430;&#x445; &#x440;&#x435;&#x43F;&#x43E;&#x437;&#x438;&#x442;&#x43E;&#x440;&#x438;&#x44F; &#x43B;&#x435;&#x436;&#x430;&#x442; &#x432; &#x43E;&#x441;&#x43D;&#x43E;&#x432;&#x43D;&#x43E;&#x43C; Endpoints &#x434;&#x43B;&#x44F; &#x440;&#x430;&#x437;&#x43D;&#x44B;&#x445; &#x43F;&#x440;&#x43E;&#x432;&#x430;&#x439;&#x434;&#x435;&#x440;&#x43E;&#x432; &#x2013; Google, Slack &#x438; &#x442;.&#x434;..<br>
&#x421;&#x435;&#x441;&#x441;&#x438;&#x438; &#x43C;&#x44B; &#x434;&#x435;&#x43B;&#x430;&#x435;&#x43C; &#x447;&#x435;&#x440;&#x435;&#x437; cookie &#x431;&#x435;&#x437; &#x441;&#x43E;&#x445;&#x440;&#x430;&#x43D;&#x435;&#x43D;&#x438;&#x44F; &#x433;&#x434;&#x435;-&#x43B;&#x438;&#x431;&#x43E; &#x435;&#x449;&#x435;. &#x41F;&#x440;&#x438; &#x436;&#x435;&#x43B;&#x430;&#x43D;&#x438;&#x438; &#x438;&#x445; &#x43C;&#x43E;&#x436;&#x43D;&#x43E; &#x445;&#x440;&#x430;&#x43D;&#x438;&#x442;&#x44C; &#x432; memcache, redis &#x438; &#x442;.&#x434;..</p>
<p>&#x414;&#x430;&#x43B;&#x435;&#x435; &#x440;&#x430;&#x437;&#x431;&#x435;&#x440;&#x435;&#x43C;&#x441;&#x44F; &#x441; &#x448;&#x430;&#x431;&#x43B;&#x43E;&#x43D;&#x430;&#x43C;&#x438; &#x438; &#x43E;&#x442;&#x440;&#x435;&#x43D;&#x434;&#x435;&#x440;&#x438;&#x43C; &#x43F;&#x440;&#x43E;&#x441;&#x442;&#x443;&#x44E; &#x441;&#x442;&#x440;&#x430;&#x43D;&#x438;&#x446;&#x443; &#x441; &#x441;&#x441;&#x44B;&#x43B;&#x43A;&#x43E;&#x439; &#x434;&#x43B;&#x44F; &#x430;&#x432;&#x442;&#x43E;&#x440;&#x438;&#x437;&#x430;&#x446;&#x438;&#x438;. &#x414;&#x43B;&#x44F; &#x44D;&#x442;&#x43E;&#x433;&#x43E; &#x43F;&#x43E;&#x43B;&#x43E;&#x436;&#x438;&#x43C; &#x432; &#x43F;&#x430;&#x43F;&#x43A;&#x443; &#x441; &#x43F;&#x440;&#x43E;&#x435;&#x43A;&#x442;&#x43E;&#x43C; &#x444;&#x430;&#x439;&#x43B; <code>index.html</code>:</p>
<pre><code class="language-html">&lt;html&gt;
  &lt;head&gt;
    &lt;meta charset=&quot;utf-8&quot;&gt;
    &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1, shrink-to-fit=no&quot;&gt;
    &lt;meta http-equiv=&quot;x-ua-compatible&quot; content=&quot;ie=edge&quot;&gt;

    &lt;link rel=&quot;stylesheet&quot; href=&quot;https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.2/css/bootstrap.min.css&quot; integrity=&quot;sha384-y3tfxAZXuh4HwSYylfB+J125MxIs6mR5FOHamPBG064zB+AFeWH94NdvaCBm8qnd&quot; crossorigin=&quot;anonymous&quot;&gt;
  &lt;/head&gt;
  &lt;body&gt;
    &lt;div class=&quot;container&quot;&gt;
      &lt;div class=&quot;row&quot;&gt;
        &lt;div class=&quot;col-sm-4&quot;&gt;
          &lt;a href=&quot;/authorize&quot; class=&quot;btn btn-primary&quot;&gt; Authorize GA &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class=&quot;col-sm-4&quot;&gt;
        &lt;/div&gt;
        &lt;div class=&quot;col-sm-4&quot;&gt;
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;script src=&quot;https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js&quot;&gt;&lt;/script&gt;
    &lt;script src=&quot;https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.2/js/bootstrap.min.js&quot; integrity=&quot;sha384-vZ2WRJMwsjRMW/8U7i6PWi6AlO1L79snBrmgiDpgIWJ82z8eA5lenwvxbMV1PAh7&quot; crossorigin=&quot;anonymous&quot;&gt;&lt;/script&gt;
  &lt;/body&gt;
&lt;/html&gt;
</code></pre>
<p>&#x415;&#x441;&#x442;&#x435;&#x441;&#x442;&#x432;&#x435;&#x43D;&#x43D;&#x43E; &#x43F;&#x43E;&#x434;&#x43A;&#x43B;&#x44E;&#x447;&#x438;&#x43B;&#x438; &#x432;&#x435;&#x437;&#x434;&#x435;&#x441;&#x443;&#x449;&#x438;&#x439; Bootstrap. &#x414;&#x430;&#x43B;&#x435;&#x435; &#x43E;&#x442;&#x440;&#x435;&#x43D;&#x434;&#x435;&#x440;&#x438;&#x43C; &#x448;&#x430;&#x431;&#x43B;&#x43E;&#x43D;, &#x43E;&#x431;&#x440;&#x430;&#x442;&#x438;&#x43C;&#x441;&#x44F; &#x43A; &#x441;&#x435;&#x441;&#x441;&#x438;&#x438; &#x438; &#x441;&#x434;&#x435;&#x43B;&#x430;&#x435;&#x43C; &#x43B;&#x43E;&#x433;&#x438;&#x440;&#x43E;&#x432;&#x430;&#x43D;&#x438;&#x435;:</p>
<pre><code class="language-go">import(
  &quot;log&quot;
  &quot;html/template&quot;
  ...
)

...

func indexHandler(w http.ResponseWriter, r *http.Request) {
  session, err := store.Get(r, &quot;GASession&quot;)
  if err != nil {
    log.Println(&quot;IH.Error while retrieving session: &quot;, err)
  }
  log.Println(&quot;Session: &quot;, session)


  t, _ := template.ParseFiles(&quot;index.html&quot;)
  t.Execute(w, struct{}{})
}
</code></pre>
<p>&#x427;&#x442;&#x43E; &#x43C;&#x44B; &#x441;&#x434;&#x435;&#x43B;&#x430;&#x43B;&#x438; &#x2013; &#x43F;&#x43E;&#x43B;&#x443;&#x447;&#x438;&#x43B;&#x438; &#x441;&#x435;&#x441;&#x441;&#x438;&#x44E;, &#x441;&#x447;&#x438;&#x442;&#x430;&#x43B;&#x438; index.html &#x438; &#x43E;&#x442;&#x440;&#x435;&#x43D;&#x434;&#x435;&#x440;&#x438;&#x43B;&#x438; &#x441;&#x442;&#x440;&#x430;&#x43D;&#x438;&#x446;&#x443;. &#x421; &#x441;&#x435;&#x441;&#x441;&#x438;&#x435;&#x439; &#x43F;&#x43E;&#x43A;&#x430; &#x43D;&#x438;&#x447;&#x435;&#x433;&#x43E; &#x43D;&#x435; &#x434;&#x435;&#x43B;&#x430;&#x435;&#x43C;, &#x43F;&#x43E;&#x43D;&#x430;&#x434;&#x43E;&#x431;&#x438;&#x442;&#x441;&#x44F; &#x434;&#x430;&#x43B;&#x44C;&#x448;&#x435;.</p>
<p>&#x422;&#x435;&#x43F;&#x435;&#x440;&#x44C; &#x43D;&#x430;&#x434;&#x43E; &#x43E;&#x442;&#x43F;&#x440;&#x430;&#x432;&#x438;&#x442;&#x44C; &#x43F;&#x43E;&#x43B;&#x44C;&#x437;&#x43E;&#x432;&#x430;&#x442;&#x435;&#x43B;&#x44F; &#x43D;&#x430; &#x441;&#x442;&#x440;&#x430;&#x43D;&#x438;&#x446;&#x443; &#x441;&#x435;&#x440;&#x432;&#x438;&#x441;&#x430; Google, &#x433;&#x434;&#x435; &#x43E;&#x43D; &#x434;&#x430;&#x441;&#x442; &#x43D;&#x430;&#x448;&#x435;&#x43C;&#x443; &#x43F;&#x440;&#x438;&#x43B;&#x43E;&#x436;&#x435;&#x43D;&#x438;&#x44F; &#x43D;&#x435;&#x43E;&#x431;&#x445;&#x43E;&#x434;&#x438;&#x43C;&#x44B;&#x435; &#x43F;&#x440;&#x430;&#x432;&#x430;.</p>
<pre><code class="language-go">func authorizeHandler(w http.ResponseWriter, r *http.Request) {
  url := config.AuthCodeURL(&quot;state&quot;)
  http.Redirect(w, r, url, http.StatusFound)
}
</code></pre>
<p>&#x41F;&#x43E;&#x441;&#x43B;&#x435; &#x442;&#x43E;&#x433;&#x43E; &#x43A;&#x430;&#x43A; &#x43F;&#x43E;&#x43B;&#x44C;&#x437;&#x43E;&#x432;&#x430;&#x442;&#x435;&#x43B;&#x44C; &#x43D;&#x430;&#x436;&#x43C;&#x435;&#x442; &#x43A;&#x43D;&#x43E;&#x43F;&#x43A;&#x443; &quot;Allow&quot;, &#x441;&#x435;&#x440;&#x432;&#x438;&#x441; &#x43F;&#x435;&#x440;&#x435;&#x43F;&#x440;&#x430;&#x432;&#x438;&#x442; &#x435;&#x433;&#x43E; &#x43D;&#x430; &#x443;&#x440;&#x43B;, &#x43A;&#x43E;&#x442;&#x43E;&#x440;&#x44B;&#x439; &#x43C;&#x44B; &#x443;&#x43A;&#x430;&#x437;&#x430;&#x43B;&#x438; &#x432; &#x43D;&#x430;&#x441;&#x442;&#x440;&#x43E;&#x439;&#x43A;&#x430;&#x445; <strong>/connect</strong>, &#x43F;&#x43E;&#x44D;&#x442;&#x43E;&#x43C;&#x443; &#x43D;&#x430;&#x43F;&#x438;&#x448;&#x443; &#x440;&#x435;&#x430;&#x43B;&#x438;&#x437;&#x430;&#x446;&#x438;&#x44E; &#x43E;&#x431;&#x440;&#x430;&#x431;&#x43E;&#x442;&#x447;&#x438;&#x43A;&#x430; &#x44D;&#x442;&#x43E;&#x433;&#x43E; &#x434;&#x435;&#x439;&#x441;&#x442;&#x432;&#x438;&#x44F;.</p>
<pre><code class="language-go">func connectHandler(w http.ResponseWriter, r *http.Request) {
  code := r.FormValue(&quot;code&quot;)
  log.Println(&quot;AH.Code: &quot;, code)

  tok, err := config.Exchange(oauth2.NoContext, code)
  if err != nil {
    log.Fatalln(&quot;AH.Error: &quot;, err)
  }
  log.Println(&quot;AH.AccessToken: &quot;, tok)

  session, err := store.Get(r, &quot;GASession&quot;)
  if err != nil {
    log.Println(&quot;AH.Error :&quot;, err)
  }
  session.Values[&quot;access_token&quot;] = tok
  session.Save(r, w)

  http.Redirect(w, r, &quot;/&quot;, http.StatusFound)
}
</code></pre>
<p>&#x420;&#x430;&#x437;&#x431;&#x435;&#x440;&#x443; &#x43F;&#x43E;&#x434;&#x440;&#x43E;&#x431;&#x43D;&#x435;&#x435;.</p>
<pre><code class="language-go">code := r.FormValue(&quot;code&quot;)
</code></pre>
<p>&#x41A;&#x43E;&#x433;&#x434;&#x430; &#x43F;&#x43E;&#x43B;&#x44C;&#x437;&#x43E;&#x432;&#x430;&#x442;&#x435;&#x43B;&#x44F; &#x441;&#x440;&#x435;&#x434;&#x438;&#x440;&#x435;&#x43A;&#x442;&#x438;&#x442; &#x43E;&#x431;&#x440;&#x430;&#x442;&#x43D;&#x43E; &#x43A; &#x43D;&#x430;&#x43C;, &#x432; &#x43F;&#x430;&#x440;&#x430;&#x43C;&#x435;&#x442;&#x440;&#x430;&#x445; &#x437;&#x430;&#x43F;&#x440;&#x43E;&#x441;&#x430; &#x432; &#x441;&#x441;&#x44B;&#x43B;&#x43A;&#x435; &#x431;&#x443;&#x434;&#x435;&#x442; &#x43F;&#x43E;&#x43B;&#x435; <code>code</code> &#x2013; &#x43F;&#x440;&#x43E;&#x432;&#x435;&#x440;&#x43E;&#x447;&#x43D;&#x44B;&#x439; &#x43A;&#x43E;&#x434;, &#x43F;&#x43E; &#x43A;&#x43E;&#x442;&#x43E;&#x440;&#x43E;&#x43C;&#x443; &#x43C;&#x44B; &#x43F;&#x43E;&#x43B;&#x443;&#x447;&#x438;&#x43C; <strong>access_token</strong> &#x441; &#x43F;&#x43E;&#x43C;&#x43E;&#x449;&#x44C;&#x44E; &#x43C;&#x435;&#x442;&#x43E;&#x434;&#x430; <code>Exchange</code> &#x438;&#x437; &#x431;&#x438;&#x431;&#x43B;&#x438;&#x43E;&#x442;&#x435;&#x43A;&#x438; <code>oauth2</code>.</p>
<pre><code class="language-go">tok, err := config.Exchange(oauth2.NoContext, code)
</code></pre>
<p>&#x41A; &#x441;&#x43E;&#x436;&#x430;&#x43B;&#x435;&#x43D;&#x438;&#x44E; &#x441;&#x43A;&#x43B;&#x430;&#x434;&#x44B;&#x432;&#x430;&#x442;&#x44C; &#x432;&#x441;&#x435; &#x43F;&#x43E;&#x434;&#x440;&#x44F;&#x434; &#x432; &#x43E;&#x431;&#x44A;&#x435;&#x43A;&#x442; &#x441;&#x435;&#x441;&#x441;&#x438;&#x438; &#x443; &#x43D;&#x430;&#x441; &#x43D;&#x435; &#x43F;&#x43E;&#x43B;&#x443;&#x447;&#x438;&#x442;&#x44C;&#x441;&#x44F;. &#x427;&#x442;&#x43E;&#x431;&#x44B; &#x441;&#x43E;&#x445;&#x440;&#x430;&#x43D;&#x438;&#x442;&#x44C; &#x442;&#x430;&#x43C; &#x447;&#x442;&#x43E;-&#x442;&#x43E; &#x43E;&#x442;&#x43B;&#x438;&#x447;&#x43D;&#x43E;&#x435; &#x43E;&#x442; &#x441;&#x442;&#x430;&#x43D;&#x434;&#x430;&#x440;&#x442;&#x43D;&#x44B;&#x445; &#x442;&#x438;&#x43F;&#x43E;&#x432; &#x43D;&#x443;&#x436;&#x43D;&#x43E; &#x437;&#x430;&#x440;&#x435;&#x433;&#x438;&#x441;&#x442;&#x440;&#x438;&#x440;&#x43E;&#x432;&#x430;&#x442;&#x44C; &#x442;&#x438;&#x43F;, &#x43A;&#x43E;&#x442;&#x43E;&#x440;&#x44B;&#x439; &#x43C;&#x44B; &#x445;&#x43E;&#x442;&#x438;&#x43C; &#x441;&#x43E;&#x445;&#x440;&#x430;&#x43D;&#x438;&#x442;&#x44C;. &#x420;&#x435;&#x433;&#x438;&#x441;&#x442;&#x440;&#x438;&#x440;&#x443;&#x435;&#x442;&#x441;&#x44F; &#x43E;&#x43D; &#x432; &#x444;&#x443;&#x43D;&#x43A;&#x446;&#x438;&#x438; <code>init()</code>. &#x41E;&#x43D;&#x430; &#x432;&#x44B;&#x437;&#x44B;&#x432;&#x430;&#x435;&#x442;&#x441;&#x44F; &#x43F;&#x43E;&#x441;&#x43B;&#x435; &#x432;&#x441;&#x435;&#x445; &#x43E;&#x43F;&#x440;&#x435;&#x434;&#x435;&#x43B;&#x435;&#x43D;&#x438;&#x439; &#x43A;&#x43E;&#x43D;&#x441;&#x442;&#x430;&#x43D;&#x442; &#x438; &#x43F;&#x435;&#x440;&#x435;&#x43C;&#x435;&#x43D;&#x43D;&#x44B;&#x445; &#x438; &#x434;&#x43E; &#x432;&#x44B;&#x437;&#x43E;&#x432;&#x430; &#x444;&#x443;&#x43D;&#x43A;&#x446;&#x438;&#x438; <code>main()</code>.</p>
<pre><code class="language-go">func init() {
  gob.Register(&amp;oauth2.Token{})
}
</code></pre>
<p>&#x414;&#x430;&#x43B;&#x435;&#x435; &#x441;&#x43E;&#x445;&#x440;&#x430;&#x43D;&#x438;&#x43C; &#x43E;&#x431;&#x44A;&#x435;&#x43A;&#x442; &#x441;&#x435;&#x441;&#x441;&#x438;&#x438; &#x434;&#x43E; &#x43E;&#x442;&#x43F;&#x440;&#x430;&#x432;&#x43A;&#x438; &#x43E;&#x442;&#x432;&#x435;&#x442;&#x430;:</p>
<pre><code class="language-go">func connectHandler(w http.ResponseWriter, r *http.Request) {
  ...
  session.Values[&quot;access_token&quot;] = tok
  session.Save(r, w)
  log.Println(&quot;AH.Session: &quot;, session)

  http.Redirect(w, r, &quot;/&quot;, http.StatusFound)
}
</code></pre>
<p>&#x422;&#x435;&#x43F;&#x435;&#x440;&#x44C; &#x432; <code>indexHandler</code> &#x43C;&#x44B; &#x43C;&#x43E;&#x436;&#x435;&#x43C; &#x43E;&#x431;&#x440;&#x430;&#x442;&#x438;&#x442;&#x44C;&#x441;&#x44F; &#x43A; &#x441;&#x435;&#x441;&#x441;&#x438;&#x438; &#x438; &#x432;&#x44B;&#x442;&#x430;&#x449;&#x438;&#x442;&#x44C; <code>access_token</code> &#x434;&#x43B;&#x44F; &#x434;&#x430;&#x43B;&#x44C;&#x43D;&#x435;&#x439;&#x448;&#x435;&#x439; &#x440;&#x430;&#x431;&#x43E;&#x442;&#x44B;. &#x412; &#x434;&#x440;&#x443;&#x433;&#x438;&#x445; &#x43E;&#x431;&#x440;&#x430;&#x431;&#x43E;&#x442;&#x447;&#x438;&#x43A;&#x430;&#x445; &#x43C;&#x44B; &#x442;&#x430;&#x43A;&#x436;&#x435; &#x43C;&#x43E;&#x436;&#x435;&#x43C; &#x43E;&#x431;&#x440;&#x430;&#x449;&#x430;&#x442;&#x44C;&#x441;&#x44F; &#x43A; <code>access_token</code> &#x438; &#x438;&#x441;&#x43F;&#x43E;&#x43B;&#x44C;&#x437;&#x43E;&#x432;&#x430;&#x442;&#x44C; &#x435;&#x433;&#x43E; &#x434;&#x43B;&#x44F; &#x438;&#x43D;&#x438;&#x446;&#x438;&#x430;&#x43B;&#x438;&#x437;&#x430;&#x446;&#x438;&#x438; &#x43A;&#x43B;&#x438;&#x435;&#x43D;&#x442;&#x430; &#x434;&#x43B;&#x44F; &#x437;&#x430;&#x43F;&#x440;&#x43E;&#x441;&#x43E;&#x432; &#x432; API Google Analytics.</p>
<p>&#x41D;&#x430; &#x44D;&#x442;&#x43E;&#x43C; &#x437;&#x430;&#x43A;&#x43E;&#x43D;&#x447;&#x443; &#x43F;&#x435;&#x440;&#x432;&#x443;&#x44E; &#x447;&#x430;&#x441;&#x442;&#x44C;. &#x412;&#x43E; &#x432;&#x442;&#x43E;&#x440;&#x43E;&#x439; &#x440;&#x430;&#x441;&#x441;&#x43A;&#x430;&#x436;&#x443; &#x43A;&#x430;&#x43A; &#x438;&#x441;&#x43F;&#x43E;&#x43B;&#x44C;&#x437;&#x43E;&#x432;&#x430;&#x442;&#x44C; &#x431;&#x438;&#x431;&#x43B;&#x438;&#x43E;&#x442;&#x435;&#x43A;&#x443; <code>google.golang.org/api/</code> &#x434;&#x43B;&#x44F; &#x437;&#x430;&#x43F;&#x440;&#x43E;&#x441;&#x43E;&#x432; &#x432; API Google.</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[SSH Config]]></title><description><![CDATA[<p>&#x421;&#x435;&#x433;&#x43E;&#x434;&#x43D;&#x44F; &#x440;&#x430;&#x441;&#x441;&#x43A;&#x430;&#x436;&#x443; &#x43F;&#x440;&#x43E; &#x443;&#x43F;&#x440;&#x43E;&#x449;&#x435;&#x43D;&#x438;&#x435; &#x436;&#x438;&#x437;&#x43D;&#x438; &#x441; ssh config. &#x41F;&#x43E; &#x440;&#x430;&#x431;&#x43E;&#x442;&#x435; &#x43F;&#x440;&#x438;&#x445;&#x43E;&#x434;&#x438;</p>]]></description><link>https://igkuz.ru/ssh-config/</link><guid isPermaLink="false">5e9209026d9007355d8bde54</guid><category><![CDATA[разработка]]></category><category><![CDATA[рабочее окружение]]></category><category><![CDATA[ssh]]></category><dc:creator><![CDATA[Igor Kuznetsov]]></dc:creator><pubDate>Sat, 20 Feb 2016 18:36:52 GMT</pubDate><content:encoded><![CDATA[<p>&#x421;&#x435;&#x433;&#x43E;&#x434;&#x43D;&#x44F; &#x440;&#x430;&#x441;&#x441;&#x43A;&#x430;&#x436;&#x443; &#x43F;&#x440;&#x43E; &#x443;&#x43F;&#x440;&#x43E;&#x449;&#x435;&#x43D;&#x438;&#x435; &#x436;&#x438;&#x437;&#x43D;&#x438; &#x441; ssh config. &#x41F;&#x43E; &#x440;&#x430;&#x431;&#x43E;&#x442;&#x435; &#x43F;&#x440;&#x438;&#x445;&#x43E;&#x434;&#x438;&#x442;&#x441;&#x44F; &#x445;&#x43E;&#x434;&#x438;&#x442;&#x44C; &#x43F;&#x43E; &#x43C;&#x43D;&#x43E;&#x436;&#x435;&#x441;&#x442;&#x432;&#x443; &#x440;&#x430;&#x437;&#x43D;&#x44B;&#x445; &#x441;&#x435;&#x440;&#x432;&#x435;&#x440;&#x43E;&#x432; &#x438; &#x434;&#x43E;&#x432;&#x43E;&#x43B;&#x44C;&#x43D;&#x43E; &#x447;&#x430;&#x441;&#x442;&#x43E;. &#x418; &#x43A;&#x430;&#x43A; &#x431;&#x44B; &#x44D;&#x442;&#x43E; &#x43D;&#x435; &#x431;&#x44B;&#x43B;&#x43E; &#x441;&#x43C;&#x435;&#x448;&#x43D;&#x43E;, &#x43D;&#x43E; ssh config &#x43E;&#x442;&#x43A;&#x440;&#x44B;&#x43B; &#x434;&#x43B;&#x44F; &#x441;&#x435;&#x431;&#x44F; &#x43F;&#x430;&#x440;&#x443; &#x434;&#x43D;&#x435;&#x439; &#x43D;&#x430;&#x437;&#x430;&#x434;.</p><p>&#x41F;&#x440;&#x435;&#x434;&#x441;&#x442;&#x430;&#x432;&#x438;&#x43C; &#x441;&#x438;&#x442;&#x443;&#x430;&#x446;&#x438;&#x44E;:</p><pre><code class="language-bash">ssh -p 22 user@host1</code></pre><p>&#x414;&#x43B;&#x44F; 1 &#x441;&#x435;&#x440;&#x432;&#x435;&#x440;&#x430; &#x43D;&#x430;&#x431;&#x438;&#x440;&#x430;&#x442;&#x44C; &#x43D;&#x435;&#x434;&#x43E;&#x43B;&#x433;&#x43E;, &#x437;&#x430;&#x43F;&#x43E;&#x43C;&#x43D;&#x438;&#x442;&#x44C; &#x43B;&#x435;&#x433;&#x43A;&#x43E;. &#x410; &#x442;&#x435;&#x43F;&#x435;&#x440;&#x44C; &#x43F;&#x440;&#x435;&#x434;&#x441;&#x442;&#x430;&#x432;&#x438;&#x43C; 30-40-50 &#x440;&#x430;&#x437;&#x43D;&#x44B;&#x445; &#x43C;&#x430;&#x448;&#x438;&#x43D;, &#x441; &#x440;&#x430;&#x437;&#x43D;&#x44B;&#x43C;&#x438; &#x43F;&#x43E;&#x440;&#x442;&#x430;&#x43C;&#x438;, &#x438;&#x43C;&#x435;&#x43D;&#x430;&#x43C;&#x438; &#x43F;&#x43E;&#x43B;&#x44C;&#x437;&#x43E;&#x432;&#x430;&#x442;&#x435;&#x43B;&#x44F; &#x438; ip &#x430;&#x434;&#x440;&#x435;&#x441;&#x430;&#x43C;&#x438;.<br>&#x412; &#x438;&#x442;&#x43E;&#x433;&#x435; &#x438;&#x43C;&#x435;&#x435;&#x43C; &#x444;&#x430;&#x439;&#x43B;&#x438;&#x43A;:</p><pre><code class="language-bash">ssh -p PORT_NUMBER user1@host1 # dev
ssh -p PORT_NUMBER user2@host2 # prod
...
ssh -p PORT_NUMBER user100@host100 # prod100
</code></pre><p>Ctrl+C &#x438; Ctrl+V &#x438; &#x43F;&#x43E;&#x433;&#x43D;&#x430;&#x43B;&#x438;. &#x41D;&#x43E; &#x44D;&#x442;&#x43E; &#x43D;&#x435; &#x43A;&#x440;&#x443;&#x442;&#x43E;, &#x43F;&#x43E;&#x44D;&#x442;&#x43E;&#x43C;&#x443; &#x432; .bashrc &#x438;&#x43B;&#x438; .zshrc &#x434;&#x43E;&#x431;&#x430;&#x432;&#x43B;&#x44F;&#x44E;&#x442;&#x441;&#x44F; &#x430;&#x43B;&#x438;&#x430;&#x441;&#x44B;:</p><pre><code class="language-bash">alias dev=&apos;ssh -p PORT_NUMBER user1@host1&apos;
alias prod1=&apos;ssh -p PORT_NUMBER user2@host2&apos;
...
alias prod100=&apos;ssh -p PORT_NUMBER user100@host100&apos;
</code></pre><p>&#x423;&#x436;&#x435; &#x43B;&#x443;&#x447;&#x448;&#x435;, &#x43D;&#x43E; &#x43E;&#x43A;&#x430;&#x437;&#x44B;&#x432;&#x430;&#x435;&#x442;&#x441;&#x44F; &#x43C;&#x43E;&#x436;&#x43D;&#x43E; &#x438; &#x435;&#x449;&#x435; &#x43A;&#x440;&#x443;&#x447;&#x435;. &#x422;&#x443;&#x442; &#x43D;&#x430;&#x43C; &#x43F;&#x43E;&#x43C;&#x43E;&#x436;&#x435;&#x442; ssh config, &#x43F;&#x43E;&#x434;&#x440;&#x43E;&#x431;&#x43D;&#x430;&#x44F; &#x434;&#x43E;&#x43A;&#x443;&#x43C;&#x435;&#x43D;&#x442;&#x430;&#x446;&#x438;&#x44F; <a href="http://linux.die.net/man/5/ssh_config?ref=igkuz.ru">&#x442;&#x443;&#x442;</a>.</p><p>2 &#x432;&#x430;&#x440;&#x438;&#x430;&#x43D;&#x442;&#x430; &#x438;&#x441;&#x43F;&#x43E;&#x43B;&#x44C;&#x437;&#x43E;&#x432;&#x430;&#x43D;&#x438;&#x44F;:</p><ul><li>/etc/ssh/ssh_config &#x2013; &#x43D;&#x430; &#x432;&#x441;&#x44E; &#x441;&#x438;&#x441;&#x442;&#x435;&#x43C;&#x443;</li><li>~/.ssh/config &#x2013; &#x434;&#x43B;&#x44F; &#x43F;&#x43E;&#x43B;&#x44C;&#x437;&#x43E;&#x432;&#x430;&#x442;&#x435;&#x43B;&#x44F;</li></ul><p>&#x420;&#x430;&#x441;&#x441;&#x43C;&#x43E;&#x442;&#x440;&#x438;&#x43C; &#x43F;&#x43E;&#x441;&#x43B;&#x435;&#x434;&#x43D;&#x438;&#x439;. &#x421;&#x43E;&#x437;&#x434;&#x430;&#x435;&#x43C; &#x438; &#x437;&#x430;&#x43F;&#x43E;&#x43B;&#x43D;&#x44F;&#x435;&#x43C;:</p><pre><code class="language-bash"># dev machine
Host dev
  HostName 127.0.0.1
  Port 22
  User username
</code></pre><p>&#x422;&#x435;&#x43F;&#x435;&#x440;&#x44C; &#x43C;&#x44B; &#x43C;&#x43E;&#x436;&#x435;&#x43C; &#x43D;&#x430;&#x431;&#x440;&#x430;&#x442;&#x44C; <code>ssh dev</code> &#x438; &#x43F;&#x43E;&#x43F;&#x430;&#x441;&#x442;&#x44C; &#x43D;&#x430; &#x43C;&#x430;&#x448;&#x438;&#x43D;&#x443;. &#x415;&#x441;&#x43B;&#x438; &#x43D;&#x430;&#x434;&#x43E; &#x43F;&#x440;&#x43E;&#x431;&#x440;&#x43E;&#x441;&#x438;&#x442;&#x44C; &#x43A;&#x43B;&#x44E;&#x447;&#x438; &#x43D;&#x430; &#x441;&#x435;&#x440;&#x432;&#x435;&#x440; &#x434;&#x43E;&#x431;&#x430;&#x432;&#x43B;&#x44F;&#x435;&#x43C;:</p><pre><code class="language-bash"># dev machine
Host dev
  HostName 127.0.0.1
  Port 22
  ForwardAgent yes
  User username
</code></pre><p>&#x41C;&#x43E;&#x436;&#x43D;&#x43E; &#x443;&#x43A;&#x430;&#x437;&#x430;&#x442;&#x44C; &#x43D;&#x430;&#x441;&#x442;&#x440;&#x43E;&#x439;&#x43A;&#x438; &#x434;&#x43B;&#x44F; &#x433;&#x440;&#x443;&#x43F;&#x43F;&#x44B; &#x441;&#x435;&#x440;&#x432;&#x435;&#x440;&#x43E;&#x432;. &#x41F;&#x440;&#x435;&#x434;&#x43F;&#x43E;&#x43B;&#x43E;&#x436;&#x438;&#x43C; &#x43D;&#x430; &#x432;&#x441;&#x435;&#x445; <code>production</code> &#x441;&#x435;&#x440;&#x432;&#x435;&#x440;&#x430;&#x445; &#x443; &#x432;&#x430;&#x441; &#x43F;&#x435;&#x440;&#x435;&#x432;&#x435;&#x448;&#x435;&#x43D; &#x43F;&#x43E;&#x440;&#x442; ssh &#x441;&#x43E; &#x441;&#x442;&#x430;&#x43D;&#x434;&#x430;&#x440;&#x442;&#x43D;&#x43E;&#x433;&#x43E; 22 &#x43D;&#x430; 2222. &#x41F;&#x43E;&#x43B;&#x44C;&#x437;&#x43E;&#x432;&#x430;&#x442;&#x435;&#x43B;&#x44C; &#x432;&#x435;&#x437;&#x434;&#x435; &#x43E;&#x434;&#x438;&#x43D;&#x430;&#x43A;&#x43E;&#x432;&#x44B;&#x439; &#x438; &#x432;&#x435;&#x437;&#x434;&#x435; &#x445;&#x43E;&#x442;&#x438;&#x43C; &#x43F;&#x440;&#x43E;&#x431;&#x440;&#x430;&#x441;&#x44B;&#x432;&#x430;&#x442;&#x44C; &#x43A;&#x43B;&#x44E;&#x447;&#x438; &#x43D;&#x430; &#x441;&#x435;&#x440;&#x432;&#x435;&#x440;.</p><pre><code class="language-bash">Host prod*
  ForwardAgent yes
  Port 2222
  User username

Host prod1
  HostName 10.0.0.1

Host prod2
  HostName 10.0.0.2
...
Host prod100
  HostName 10.0.0.100
</code></pre><p>&#x411;&#x43E;&#x43D;&#x443;&#x441; - &#x430;&#x432;&#x442;&#x43E;&#x43A;&#x43E;&#x43C;&#x43F;&#x43B;&#x438;&#x442;. &#x41D;&#x430;&#x431;&#x438;&#x440;&#x430;&#x435;&#x43C; <code>ssh</code>, &#x43D;&#x430;&#x436;&#x438;&#x43C;&#x430;&#x435;&#x43C; <code>Tab</code> &#x438; &#x43F;&#x43E;&#x43A;&#x430;&#x437;&#x44B;&#x432;&#x430;&#x435;&#x442;&#x441;&#x44F; &#x441;&#x43F;&#x438;&#x441;&#x43E;&#x43A; &#x445;&#x43E;&#x441;&#x442;&#x43E;&#x432; &#x438;&#x437; &#x43A;&#x43E;&#x43D;&#x444;&#x438;&#x433;&#x430;. &#x41F;&#x440;&#x43E;&#x444;&#x438;&#x442;. &#x418;&#x437; &#x43C;&#x438;&#x43D;&#x443;&#x441;&#x43E;&#x432; - &#x43D;&#x435;&#x43B;&#x44C;&#x437;&#x44F; &#x434;&#x435;&#x43B;&#x430;&#x442;&#x44C; include &#x434;&#x440;&#x443;&#x433;&#x438;&#x445; &#x444;&#x430;&#x439;&#x43B;&#x43E;&#x432; &#x43A;&#x43E;&#x43D;&#x444;&#x438;&#x433;&#x430;, &#x442;&#x43E;&#x433;&#x434;&#x430; &#x43C;&#x43E;&#x436;&#x43D;&#x43E; &#x431;&#x44B;&#x43B;&#x43E; &#x431;&#x44B; &#x43E;&#x442;&#x43B;&#x438;&#x447;&#x43D;&#x43E; &#x43A;&#x43E;&#x43C;&#x431;&#x438;&#x43D;&#x438;&#x440;&#x43E;&#x432;&#x430;&#x442;&#x44C; &#x444;&#x430;&#x439;&#x43B;&#x44B; &#x441; &#x43B;&#x438;&#x447;&#x43D;&#x44B;&#x43C;&#x438; &#x441;&#x435;&#x440;&#x432;&#x435;&#x440;&#x430;&#x43C;&#x438; &#x438; &#x440;&#x430;&#x431;&#x43E;&#x447;&#x438;&#x43C;&#x438;.</p>]]></content:encoded></item><item><title><![CDATA[Neovim]]></title><description><![CDATA[Как установить Neovim на MacOS с менеджером пакетов vim-plug.]]></description><link>https://igkuz.ru/neovim/</link><guid isPermaLink="false">5e9209026d9007355d8bde7f</guid><category><![CDATA[vim]]></category><category><![CDATA[рабочее окружение]]></category><category><![CDATA[разработка]]></category><dc:creator><![CDATA[Igor Kuznetsov]]></dc:creator><pubDate>Mon, 18 Jan 2016 17:16:18 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>&#x41D;&#x430; &#x43D;&#x43E;&#x432;&#x43E;&#x433;&#x43E;&#x434;&#x43D;&#x438;&#x445; &#x43F;&#x440;&#x430;&#x437;&#x434;&#x43D;&#x438;&#x43A;&#x430;&#x445; &#x445;&#x43E;&#x447;&#x435;&#x442;&#x441;&#x44F; &#x432;&#x44B;&#x431;&#x440;&#x430;&#x442;&#x44C;&#x441;&#x44F; &#x438;&#x437; &#x441;&#x438;&#x43D;&#x435;&#x439; &#x44F;&#x43C;&#x44B; &#x438; &#x437;&#x430;&#x43D;&#x44F;&#x442;&#x44C;&#x441;&#x44F; &#x447;&#x435;&#x43C;-&#x442;&#x43E; &#x43F;&#x43E;&#x43B;&#x435;&#x437;&#x43D;&#x44B;&#x43C;. &#x414;&#x430;&#x432;&#x43D;&#x435;&#x435; &#x436;&#x435;&#x43B;&#x430;&#x43D;&#x438;&#x435; - &#x441;&#x43E;&#x431;&#x440;&#x430;&#x442;&#x44C; &#x441;&#x432;&#x43E;&#x439; Vim &#x441; &#x431;&#x43B;&#x44D;&#x43A;&#x434;&#x436;&#x435;&#x43A;&#x43E;&#x43C;, &#x43F;&#x43E;&#x434;&#x43E;&#x448;&#x43B;&#x43E; &#x438;&#x434;&#x435;&#x430;&#x43B;&#x44C;&#x43D;&#x43E;. &#x417;&#x430;&#x434;&#x430;&#x447;&#x430; &#x43F;&#x43E;&#x43B;&#x435;&#x437;&#x43D;&#x435;&#x435; &#x431;&#x443;&#x442;&#x44B;&#x43B;&#x43A;&#x438; &#x43F;&#x438;&#x432;&#x430; (&#x43F;&#x43E;&#x434;&#x441;&#x442;&#x430;&#x432;&#x44C; &#x43B;&#x44E;&#x431;&#x43E;&#x439; &#x430;&#x43B;&#x43A;&#x43E;&#x433;&#x43E;&#x43B;&#x44C;&#x43D;&#x44B;&#x439; &#x43D;&#x430;&#x43F;&#x438;&#x442;&#x43E;&#x43A;), &#x43F;&#x43E;&#x44D;&#x442;&#x43E;&#x43C;&#x443; &#x43F;&#x43E;&#x435;&#x445;&#x430;&#x43B;&#x438;. &#x41F;&#x43E; &#x445;&#x43E;&#x434;&#x443; &#x43F;&#x435;&#x440;&#x435;&#x435;&#x437;&#x434;&#x430; &#x432;&#x441;&#x43F;&#x43E;&#x43C;&#x43D;&#x438;&#x43B; &#x43F;&#x440;&#x43E; <a href="http://neovim.io/?ref=igkuz.ru">Neovim</a> &#x438; &#x440;&#x435;&#x448;&#x438;&#x43B; &#x43F;&#x43E;&#x43F;&#x440;&#x43E;&#x431;&#x43E;&#x432;&#x430;&#x442;&#x44C;.</p>
<p>&#x421; &#x441;&#x430;&#x43C;&#x43E;&#x433;&#x43E; &#x43D;&#x430;&#x447;&#x430;&#x43B;&#x430; &#x44F; &#x431;&#x44B;&#x43B; &#x43D;&#x430; &#x441;&#x431;&#x43E;&#x440;&#x43A;&#x435; <a href="https://github.com/carlhuda/janus?ref=igkuz.ru">Janus</a>. &#x41E;&#x442;&#x43B;&#x438;&#x447;&#x43D;&#x430;&#x44F; &#x432;&#x435;&#x449;&#x44C; &#x434;&#x43B;&#x44F; &#x43D;&#x430;&#x447;&#x438;&#x43D;&#x430;&#x44E;&#x449;&#x438;&#x445; &#x438; &#x43D;&#x435;&#x437;&#x430;&#x43C;&#x43E;&#x440;&#x430;&#x447;&#x438;&#x432;&#x430;&#x44E;&#x449;&#x438;&#x445;&#x441;&#x44F;. &#x412;&#x437;&#x44F;&#x43B; &#x432;&#x435;&#x43B;&#x43E;&#x441;&#x438;&#x43F;&#x435;&#x434;, &#x43E;&#x431;&#x43D;&#x43E;&#x432;&#x438;&#x43B; &#x43D;&#x435;&#x43C;&#x43D;&#x43E;&#x433;&#x43E; &#x440;&#x443;&#x43B;&#x435;&#x432;&#x43E;&#x435; &#x443;&#x43F;&#x440;&#x430;&#x432;&#x43B;&#x435;&#x43D;&#x438;&#x435; &#x438; &#x43F;&#x435;&#x440;&#x435;&#x43A;&#x43B;&#x44E;&#x447;&#x435;&#x43D;&#x438;&#x435; &#x441;&#x43A;&#x43E;&#x440;&#x43E;&#x441;&#x442;&#x435;&#x439;, &#x438; &#x433;&#x43E;&#x43D;&#x44F;&#x439; &#x441;&#x435;&#x431;&#x435; &#x43D;&#x430; &#x437;&#x434;&#x43E;&#x440;&#x43E;&#x432;&#x44C;&#x435;.</p>
<p>&#x41D;&#x43E; &#x43D;&#x430;&#x441;&#x442;&#x43E;&#x44F;&#x449;&#x438;&#x435; &quot;&#x43F;&#x430;&#x446;&#x430;&#x43D;&#x44B;&quot; &#x434;&#x435;&#x43B;&#x430;&#x44E;&#x442; &#x441;&#x432;&#x43E;&#x44E; &#x441;&#x431;&#x43E;&#x440;&#x43A;&#x443;. &#x41F;&#x435;&#x440;&#x435;&#x442;&#x430;&#x441;&#x43A;&#x438;&#x432;&#x430;&#x442;&#x44C; &#x441;&#x440;&#x430;&#x437;&#x443; &#x432;&#x435;&#x441;&#x44C; &#x441;&#x43F;&#x438;&#x441;&#x43E;&#x43A; &#x43F;&#x43B;&#x430;&#x433;&#x438;&#x43D;&#x43E;&#x432; &#x438;&#x437; Janus &#x431;&#x435;&#x441;&#x441;&#x43C;&#x44B;&#x441;&#x43B;&#x435;&#x43D;&#x43D;&#x43E;. &#x420;&#x435;&#x448;&#x438;&#x43B;, &#x447;&#x442;&#x43E; &#x431;&#x443;&#x434;&#x443; &#x434;&#x43E;&#x431;&#x430;&#x432;&#x43B;&#x44F;&#x442;&#x44C; &#x43D;&#x443;&#x436;&#x43D;&#x44B;&#x435; &#x43F;&#x43E; &#x43C;&#x435;&#x440;&#x435; &#x43D;&#x435;&#x43E;&#x431;&#x445;&#x43E;&#x434;&#x438;&#x43C;&#x43E;&#x441;&#x442;&#x438;. &#x41D;&#x435;&#x43E;&#x431;&#x445;&#x43E;&#x434;&#x438;&#x43C;&#x43E;&#x441;&#x442;&#x44C; &#x432;&#x43E;&#x437;&#x43D;&#x438;&#x43A;&#x43B;&#x430; &#x441;&#x440;&#x430;&#x437;&#x443; &#x438; &#x442;&#x443;&#x442; &#x436;&#x435; &#x43F;&#x440;&#x438;&#x448;&#x43B;&#x43E;&#x441;&#x44C; &#x432;&#x44B;&#x431;&#x438;&#x440;&#x430;&#x442;&#x44C; &#x43C;&#x435;&#x436;&#x434;&#x443; &#x43C;&#x435;&#x43D;&#x435;&#x434;&#x436;&#x435;&#x440;&#x430;&#x43C;&#x438; &#x437;&#x430;&#x432;&#x438;&#x441;&#x438;&#x43C;&#x43E;&#x441;&#x442;&#x435;&#x439;. &#x41F;&#x43E;&#x44D;&#x442;&#x43E;&#x43C;&#x443; &#x43D;&#x430;&#x43F;&#x438;&#x448;&#x443; &#x43D;&#x435;&#x43C;&#x43D;&#x43E;&#x433;&#x43E; &#x43F;&#x440;&#x43E; &#x43D;&#x438;&#x445;, &#x43F;&#x440;&#x435;&#x436;&#x434;&#x435; &#x447;&#x435;&#x43C; &#x43F;&#x435;&#x440;&#x435;&#x439;&#x442;&#x438; &#x43A; &#x441;&#x43F;&#x438;&#x441;&#x43A;&#x443; &#x43F;&#x43B;&#x430;&#x433;&#x438;&#x43D;&#x43E;&#x432; &#x438; &#x43E;&#x441;&#x442;&#x430;&#x43B;&#x44C;&#x43D;&#x44B;&#x43C; &#x43F;&#x440;&#x435;&#x43C;&#x443;&#x434;&#x440;&#x43E;&#x441;&#x442;&#x44F;&#x43C;.</p>
<p>&#x41D;&#x435; &#x440;&#x430;&#x437;&#x431;&#x438;&#x440;&#x430;&#x43B;&#x441;&#x44F; &#x432; &#x440;&#x430;&#x437;&#x43B;&#x438;&#x447;&#x438;&#x44F;&#x445; &#x43C;&#x435;&#x436;&#x434;&#x443; &#x43C;&#x435;&#x43D;&#x435;&#x434;&#x436;&#x435;&#x440;&#x430;&#x43C;&#x438; &#x43F;&#x43B;&#x430;&#x433;&#x438;&#x43D;&#x43E;&#x432; (&#x437;&#x430;&#x432;&#x438;&#x441;&#x438;&#x43C;&#x43E;&#x441;&#x442;&#x435;&#x439;), &#x432;&#x44B;&#x431;&#x438;&#x440;&#x430;&#x442;&#x44C; &#x43F;&#x440;&#x438;&#x448;&#x43B;&#x43E;&#x441;&#x44C; &#x43C;&#x435;&#x436;&#x434;&#x443; <a href="https://github.com/VundleVim/Vundle.vim?ref=igkuz.ru">Vundle</a> &#x438; <a href="https://github.com/junegunn/vim-plug?ref=igkuz.ru">Vim-Plug</a>. &#x41F;&#x435;&#x440;&#x432;&#x44B;&#x439; &#x43C;&#x43D;&#x43E;&#x433;&#x438;&#x43C;&#x438; &#x438;&#x441;&#x43F;&#x43E;&#x43B;&#x44C;&#x437;&#x443;&#x435;&#x442;&#x441;&#x44F;, &#x43D;&#x43E; &#x43C;&#x430;&#x43B;&#x43E; &#x43F;&#x43E;&#x434;&#x434;&#x435;&#x440;&#x436;&#x438;&#x432;&#x430;&#x435;&#x442;&#x441;&#x44F; &#x441;&#x432;&#x43E;&#x438;&#x43C; &#x441;&#x43E;&#x437;&#x434;&#x430;&#x442;&#x435;&#x43B;&#x435;&#x43C;. &#x412;&#x442;&#x43E;&#x440;&#x43E;&#x439; - &#x438;&#x437;&#x43D;&#x430;&#x447;&#x430;&#x43B;&#x44C;&#x43D;&#x44B;&#x439; &#x444;&#x43E;&#x440;&#x43A;, &#x43D;&#x43E; &#x441; &#x43A;&#x443;&#x447;&#x435;&#x439; &#x43F;&#x440;&#x438;&#x44F;&#x442;&#x43D;&#x44B;&#x445; &#x443;&#x43B;&#x443;&#x447;&#x448;&#x435;&#x43D;&#x438;&#x439;, &#x442;&#x438;&#x43F;&#x43E; lazyload &#x43F;&#x43B;&#x430;&#x433;&#x438;&#x43D;&#x43E;&#x432; &#x43F;&#x43E; &#x43D;&#x435;&#x43E;&#x431;&#x445;&#x43E;&#x434;&#x438;&#x43C;&#x43E;&#x441;&#x442;&#x438;, &#x430; &#x442;&#x430;&#x43A;&#x436;&#x435; &#x43F;&#x430;&#x440;&#x430;&#x43B;&#x43B;&#x435;&#x43B;&#x44C;&#x43D;&#x43E;&#x439; &#x437;&#x430;&#x433;&#x440;&#x443;&#x437;&#x43A;&#x43E;&#x439; &#x438; &#x443;&#x441;&#x442;&#x430;&#x43D;&#x43E;&#x432;&#x43A;&#x43E;&#x439;. &#x41F;&#x43E;&#x441;&#x43B;&#x435;&#x434;&#x43D;&#x44F;&#x44F; &#x444;&#x438;&#x447;&#x430; - &#x434;&#x43E;&#x441;&#x442;&#x430;&#x442;&#x43E;&#x447;&#x43D;&#x43E; &#x441;&#x43E;&#x43C;&#x43D;&#x438;&#x442;&#x435;&#x43B;&#x44C;&#x43D;&#x43E;&#x435; &#x43F;&#x440;&#x435;&#x438;&#x43C;&#x443;&#x449;&#x435;&#x441;&#x442;&#x432;&#x43E;. &#x410;&#x43A;&#x442;&#x443;&#x430;&#x43B;&#x44C;&#x43D;&#x430; &#x442;&#x43E;&#x43B;&#x44C;&#x43A;&#x43E; &#x43F;&#x440;&#x438; &#x43F;&#x435;&#x440;&#x435;&#x435;&#x437;&#x434;&#x435; &#x43D;&#x430; &#x43D;&#x43E;&#x432;&#x44B;&#x439; &#x43A;&#x43E;&#x43C;&#x43F;.</p>
<p>&#x41A;&#x430;&#x43A; &#x443;&#x441;&#x442;&#x430;&#x43D;&#x430;&#x432;&#x43B;&#x438;&#x432;&#x430;&#x442;&#x44C; Neovim &#x440;&#x430;&#x441;&#x441;&#x43A;&#x430;&#x437;&#x44B;&#x432;&#x430;&#x442;&#x44C; &#x431;&#x435;&#x441;&#x441;&#x43C;&#x44B;&#x441;&#x43B;&#x435;&#x43D;&#x43D;&#x43E;, &#x44F; &#x441;&#x442;&#x430;&#x432;&#x438;&#x43B; &#x447;&#x435;&#x440;&#x435;&#x437; brew.</p>
<p>&#x410; &#x432;&#x43E;&#x442; &#x43F;&#x440;&#x438; &#x43F;&#x435;&#x440;&#x432;&#x43E;&#x43D;&#x430;&#x447;&#x430;&#x43B;&#x44C;&#x43D;&#x43E;&#x439; &#x437;&#x430;&#x433;&#x440;&#x443;&#x437;&#x43A;&#x435; &#x43E;&#x442;&#x43B;&#x43E;&#x432;&#x438;&#x43B; &#x43D;&#x435;&#x441;&#x43A;&#x43E;&#x43B;&#x44C;&#x43A;&#x43E; &#x438;&#x43D;&#x442;&#x435;&#x440;&#x435;&#x441;&#x43D;&#x44B;&#x445; &#x432;&#x435;&#x449;&#x435;&#x439;.</p>
<ol>
<li>&#x43A;&#x43E;&#x43D;&#x444;&#x438;&#x433;&#x443;&#x440;&#x430;&#x446;&#x438;&#x44F; &#x43B;&#x435;&#x436;&#x438;&#x442; &#x432; <code>~/.config/nvim/init.vim</code></li>
<li>&#x431;&#x435;&#x437; &#x441;&#x43E;&#x437;&#x434;&#x430;&#x43D;&#x438;&#x44F; &#x444;&#x430;&#x439;&#x43B;&#x430; ~/.nvimrc &#x43C;&#x43E;&#x439; &#x43A;&#x43E;&#x43D;&#x444;&#x438;&#x433; &#x43D;&#x435; &#x447;&#x438;&#x442;&#x430;&#x43B;&#x441;&#x44F; (&#x43F;&#x43E;&#x447;&#x435;&#x43C;&#x443; &#x442;&#x430;&#x43A; &#x43F;&#x440;&#x43E;&#x438;&#x437;&#x43E;&#x448;&#x43B;&#x43E; &#x434;&#x43E; &#x441;&#x438;&#x445; &#x43F;&#x43E;&#x440; &#x434;&#x43B;&#x44F; &#x43C;&#x435;&#x43D;&#x44F; &#x437;&#x430;&#x433;&#x430;&#x434;&#x43A;&#x430;)</li>
</ol>
<p>2&#x43E;&#x439; &#x43F;&#x443;&#x43D;&#x43A;&#x442; &#x440;&#x435;&#x448;&#x438;&#x43B; &#x441;&#x43E;&#x437;&#x434;&#x430;&#x43D;&#x438;&#x435;&#x43C; symbol link &#x43D;&#x430; init.vim.</p>
<p>&#x415;&#x449;&#x435; &#x43E;&#x434;&#x43D;&#x430; &#x43F;&#x440;&#x43E;&#x431;&#x43B;&#x435;&#x43C;&#x430; - &#x43D;&#x435;&#x43F;&#x440;&#x430;&#x432;&#x438;&#x43B;&#x44C;&#x43D;&#x44B;&#x439; &#x43A;&#x43E;&#x434; &#x43F;&#x440;&#x438; &#x43D;&#x430;&#x436;&#x430;&#x442;&#x438;&#x438; <code>Ctrl + h</code>. &#x42D;&#x442;&#x43E; &#x43D;&#x443;&#x436;&#x43D;&#x43E; &#x434;&#x43B;&#x44F; &#x43F;&#x435;&#x440;&#x435;&#x43A;&#x43B;&#x44E;&#x447;&#x435;&#x43D;&#x438;&#x435; &#x43C;&#x435;&#x436;&#x434;&#x443; &#x43E;&#x43A;&#x43D;&#x430;&#x43C;&#x438;, &#x43D;&#x430;&#x43F;&#x440;&#x438;&#x43C;&#x435;&#x440; &#x441; NERDTree. &#x412; iTerm &#x441;&#x434;&#x435;&#x43B;&#x430;&#x43B; &#x442;&#x430;&#x43A;.</p>
<p><img src="https://igkuz.ru/content/images/2016/01/--------------2016-01-15---15-23-06.png" alt="&#x412;&#x43E;&#x442; &#x442;&#x430;&#x43A; &#x44D;&#x442;&#x43E; &#x440;&#x435;&#x448;&#x430;&#x435;&#x442;&#x441;&#x44F;." loading="lazy"></p>
<p>&#x41F;&#x43E;&#x43A;&#x430; &#x443; &#x43C;&#x435;&#x43D;&#x44F; &#x43D;&#x435; &#x43F;&#x43E;&#x43B;&#x443;&#x447;&#x438;&#x43B;&#x43E;&#x441;&#x44C; &#x43F;&#x440;&#x438;&#x43A;&#x440;&#x443;&#x442;&#x438;&#x442;&#x44C; <a href="https://github.com/Valloric/YouCompleteMe?ref=igkuz.ru">YCM</a>, &#x43D;&#x43E; &#x440;&#x430;&#x431;&#x43E;&#x442;&#x430;&#x442;&#x44C; &#x443;&#x436;&#x435; &#x43C;&#x43E;&#x436;&#x43D;&#x43E;.</p>
<p>&#x412;&#x44B;&#x432;&#x43E;&#x434;&#x44B; - Neovim &#x445;&#x43E;&#x440;&#x43E;&#x448;, &#x43D;&#x43E; &#x441;&#x44B;&#x440;&#x43E;&#x432;&#x430;&#x442;. &#x421;&#x43B;&#x43E;&#x436;&#x43D;&#x43E; &#x43D;&#x430;&#x439;&#x442;&#x438; &#x440;&#x435;&#x448;&#x435;&#x43D;&#x438;&#x435; &#x43F;&#x440;&#x43E;&#x431;&#x43B;&#x435;&#x43C; &#x43F;&#x440;&#x438;&#x43C;&#x435;&#x43D;&#x438;&#x442;&#x435;&#x43B;&#x44C;&#x43D;&#x43E; &#x43A; &#x43D;&#x435;&#x43C;&#x443;. &#x421; Vim&#x43E;&#x43C; &#x43F;&#x43E;&#x43B;&#x43D;&#x43E; &#x43E;&#x431;&#x441;&#x443;&#x436;&#x434;&#x435;&#x43D;&#x438;&#x439; &#x438; &#x431;&#x43B;&#x43E;&#x433;&#x43E;&#x432;. &#x421;&#x442;&#x43E;&#x438;&#x442; &#x43B;&#x438; &#x43E;&#x431;&#x43D;&#x43E;&#x432;&#x43B;&#x44F;&#x442;&#x44C;&#x441;&#x44F; - &#x440;&#x435;&#x448;&#x430;&#x442;&#x44C; &#x432;&#x430;&#x43C;.</p>
<p><strong>P.S.</strong> &#x420;&#x430;&#x437;&#x440;&#x430;&#x431;&#x43E;&#x442;&#x447;&#x438;&#x43A; neovim &#x441;&#x434;&#x435;&#x43B;&#x430;&#x43B; &#x43E;&#x447;&#x435;&#x43D;&#x44C; &#x43A;&#x440;&#x443;&#x442;&#x43E;. &#x412;&#x431;&#x440;&#x43E;&#x441;&#x438;&#x43B; &#x43D;&#x430; kickstarter (&#x438;&#x43B;&#x438; &#x441;&#x445;&#x43E;&#x436;&#x435;&#x43C; &#x440;&#x435;&#x441;&#x443;&#x440;&#x441;&#x435;) &#x43F;&#x440;&#x43E; &#x43D;&#x43E;&#x432;&#x44B;&#x439; vim, &#x441;&#x43E;&#x431;&#x440;&#x430;&#x43B; &#x43D;&#x430;&#x447;&#x430;&#x43B;&#x44C;&#x43D;&#x44B;&#x439; &#x43A;&#x430;&#x43F;&#x438;&#x442;&#x430;&#x43B;, &#x447;&#x442;&#x43E;&#x431;&#x44B; &#x440;&#x430;&#x431;&#x43E;&#x442;&#x430;&#x442;&#x44C; &#x43D;&#x430;&#x434; &#x43D;&#x438;&#x43C; full-time, &#x430; &#x442;&#x435;&#x43F;&#x435;&#x440;&#x44C; &#x43A;&#x430;&#x436;&#x434;&#x44B;&#x439; &#x43C;&#x435;&#x441;&#x44F;&#x446; &#x441;&#x43E;&#x431;&#x438;&#x440;&#x430;&#x435;&#x442; &#x43F;&#x43E; $4-5k, &#x447;&#x442;&#x43E;&#x431;&#x44B; &#x434;&#x430;&#x43B;&#x44C;&#x448;&#x435; &#x43D;&#x430;&#x434; &#x43D;&#x438;&#x43C; &#x440;&#x430;&#x431;&#x43E;&#x442;&#x430;&#x442;&#x44C;. &#x423;&#x447;&#x438;&#x442;&#x435;&#x441;&#x44C;.</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Uber в путешествии по Азии]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>&#x421;&#x435;&#x433;&#x43E;&#x434;&#x43D;&#x44F; &#x43D;&#x430;&#x447;&#x43D;&#x443; &#x43F;&#x438;&#x441;&#x430;&#x442;&#x44C; &#x43D;&#x430; &#x43D;&#x43E;&#x432;&#x443;&#x44E; &#x434;&#x43B;&#x44F; &#x431;&#x43B;&#x43E;&#x433;&#x430; &#x442;&#x435;&#x43C;&#x443; &#x2014; &#x43F;&#x443;&#x442;&#x435;&#x448;&#x435;&#x441;&#x442;&#x432;&#x438;&#x44F;. &#x41C;</p>]]></description><link>https://igkuz.ru/ubier-v-putieshiestvii/</link><guid isPermaLink="false">5e9209026d9007355d8bde80</guid><category><![CDATA[uber]]></category><category><![CDATA[путешествие]]></category><dc:creator><![CDATA[Igor Kuznetsov]]></dc:creator><pubDate>Wed, 16 Sep 2015 09:26:37 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>&#x421;&#x435;&#x433;&#x43E;&#x434;&#x43D;&#x44F; &#x43D;&#x430;&#x447;&#x43D;&#x443; &#x43F;&#x438;&#x441;&#x430;&#x442;&#x44C; &#x43D;&#x430; &#x43D;&#x43E;&#x432;&#x443;&#x44E; &#x434;&#x43B;&#x44F; &#x431;&#x43B;&#x43E;&#x433;&#x430; &#x442;&#x435;&#x43C;&#x443; &#x2014; &#x43F;&#x443;&#x442;&#x435;&#x448;&#x435;&#x441;&#x442;&#x432;&#x438;&#x44F;. &#x41C;&#x44B; &#x43F;&#x440;&#x43E;&#x433;&#x440;&#x430;&#x43C;&#x43C;&#x438;&#x441;&#x442;&#x44B; &#x2014; &#x43D;&#x430;&#x440;&#x43E;&#x434; &#x437;&#x430;&#x43A;&#x440;&#x44B;&#x442;&#x44B;&#x439;, &#x43D;&#x43E; &#x43F;&#x443;&#x442;&#x435;&#x448;&#x435;&#x441;&#x442;&#x432;&#x43E;&#x432;&#x430;&#x442;&#x44C; &#x43B;&#x44E;&#x431;&#x438;&#x43C; &#x43D;&#x435; &#x442;&#x43E;&#x43B;&#x44C;&#x43A;&#x43E; &#x43F;&#x43E; &#x43F;&#x440;&#x43E;&#x441;&#x442;&#x43E;&#x440;&#x430;&#x43C; &#x438;&#x43D;&#x442;&#x435;&#x440;&#x43D;&#x435;&#x442;&#x430;.</p>
<p>&#x41D;&#x430;&#x447;&#x43D;&#x443; &#x440;&#x430;&#x441;&#x441;&#x43A;&#x430;&#x437; &#x43E; &#x442;&#x43E;&#x43C;, &#x447;&#x442;&#x43E; &#x43C;&#x435;&#x43D;&#x44F; &#x43F;&#x43E;&#x440;&#x430;&#x437;&#x438;&#x43B;&#x43E; &#x432; &#x44D;&#x442;&#x43E;&#x442; &#x440;&#x430;&#x437;. &#x414;&#x443;&#x43C;&#x430;&#x44E; &#x43A;&#x43E;&#x43C;&#x43F;&#x430;&#x43D;&#x438;&#x44E; Uber &#x443;&#x436;&#x435; &#x43F;&#x440;&#x435;&#x434;&#x441;&#x442;&#x430;&#x432;&#x43B;&#x44F;&#x442;&#x44C; &#x43D;&#x438;&#x43A;&#x43E;&#x43C;&#x443; &#x43D;&#x435; &#x43D;&#x443;&#x436;&#x43D;&#x43E;. &#x41E; &#x43D;&#x438;&#x445; &#x43C;&#x43D;&#x43E;&#x433;&#x43E; &#x43D;&#x430;&#x43F;&#x438;&#x441;&#x430;&#x43D;&#x43E;. &#x422;&#x430;&#x43A;&#x441;&#x438;&#x441;&#x442;&#x44B; &#x43D;&#x430;&#x447;&#x430;&#x43B;&#x438; &#x441; &#x43D;&#x438;&#x43C;&#x438; &#x432;&#x43E;&#x439;&#x43D;&#x44B; &#x438; &#x43F;&#x435;&#x440;&#x435;&#x432;&#x43E;&#x440;&#x430;&#x447;&#x438;&#x432;&#x430;&#x44E;&#x442; &#x438;&#x445; &#x43C;&#x435;&#x440;&#x441;&#x435;&#x434;&#x435;&#x441;&#x44B;, &#x447;&#x442;&#x43E; &#x437;&#x430;&#x431;&#x430;&#x432;&#x43D;&#x43E;. &#x42D;&#x442;&#x43E; &#x441;&#x432;&#x438;&#x434;&#x435;&#x442;&#x435;&#x43B;&#x44C;&#x441;&#x442;&#x432;&#x43E; &#x442;&#x43E;&#x433;&#x43E;, &#x447;&#x442;&#x43E; &#x43A;&#x43E;&#x43C;&#x43F;&#x430;&#x43D;&#x438;&#x44F; &#x434;&#x435;&#x439;&#x441;&#x442;&#x432;&#x438;&#x442;&#x435;&#x43B;&#x44C;&#x43D;&#x43E; &#x434;&#x435;&#x43B;&#x430;&#x435;&#x442; &#x440;&#x435;&#x432;&#x43E;&#x43B;&#x44E;&#x446;&#x438;&#x43E;&#x43D;&#x43D;&#x44B;&#x435; &#x432;&#x435;&#x449;&#x438;. &#x41D;&#x43E; &#x445;&#x432;&#x430;&#x442;&#x438;&#x442; &#x43B;&#x438;&#x440;&#x438;&#x43A;&#x438;, &#x43F;&#x435;&#x440;&#x435;&#x439;&#x434;&#x435;&#x43C; &#x43A; &#x441;&#x443;&#x442;&#x438;.</p>
<p>&#x41C;&#x43E;&#x441;&#x43A;&#x432;&#x443; &#x438; &#x41F;&#x438;&#x442;&#x435;&#x440; Uber&apos;&#x43E;&#x43C; &#x443;&#x436;&#x435; &#x43D;&#x435; &#x443;&#x434;&#x438;&#x432;&#x438;&#x442;&#x44C;, &#x43D;&#x43E; &#x432; &#x43F;&#x440;&#x43E;&#x432;&#x438;&#x43D;&#x446;&#x438;&#x44F;&#x445; &#x43D;&#x430;&#x448;&#x435;&#x439; &#x432;&#x435;&#x43B;&#x438;&#x43A;&#x43E;&#x439; &#x440;&#x43E;&#x434;&#x438;&#x43D;&#x44B; &#x43E; &#x43D;&#x435;&#x43C; &#x432;&#x441;&#x435; &#x435;&#x449;&#x435; &#x43D;&#x435; &#x441;&#x43B;&#x44B;&#x448;&#x43D;&#x43E;. &#x41F;&#x440;&#x438;&#x43B;&#x435;&#x442;&#x435;&#x43B;&#x438; &#x432; &#x425;&#x430;&#x43D;&#x43E;&#x439;, &#x43F;&#x435;&#x440;&#x432;&#x44B;&#x43C; &#x434;&#x435;&#x43B;&#x43E;&#x43C; &#x43A;&#x443;&#x43F;&#x438;&#x43B;&#x438; &#x441;&#x438;&#x43C;&#x43A;&#x443; &#x438; &#x443;&#x437;&#x43D;&#x430;&#x43B;&#x438; &#x441;&#x442;&#x43E;&#x438;&#x43C;&#x43E;&#x441;&#x442;&#x44C; &#x442;&#x430;&#x43A;&#x441;&#x438; &#x434;&#x43E; &#x43E;&#x442;&#x435;&#x43B;&#x44F; &#x2014; $24. &#x418; &#x442;&#x443;&#x442; &#x44F; &#x432;&#x441;&#x43F;&#x43E;&#x43C;&#x43D;&#x438;&#x43B; &#x43F;&#x440;&#x43E; Uber. &#x41E;&#x43A;&#x430;&#x437;&#x44B;&#x432;&#x430;&#x435;&#x442;&#x441;&#x44F; &#x432; &#x441;&#x442;&#x43E;&#x43B;&#x438;&#x446;&#x435; &#x441;&#x43E;&#x446;&#x438;&#x430;&#x43B;&#x438;&#x441;&#x442;&#x438;&#x447;&#x435;&#x441;&#x43A;&#x43E;&#x433;&#x43E; &#x433;&#x43E;&#x441;&#x443;&#x434;&#x430;&#x440;&#x441;&#x442;&#x432;&#x430; &#x412;&#x44C;&#x435;&#x442;&#x43D;&#x430;&#x43C; &#x440;&#x430;&#x431;&#x43E;&#x442;&#x430;&#x435;&#x442; Uber black &#x438; Uber X.</p>
<p>&#x412;&#x438;&#x43F;, &#x43B;&#x430;&#x43A;&#x448;&#x435;&#x440;&#x438;, &#x434;&#x435;&#x43B;&#x44E;&#x43A;&#x441; &#x438; &#x43F;&#x440;&#x435;&#x43C;&#x438;&#x443;&#x43C; - &#x44D;&#x442;&#x43E; &#x43A;&#x43B;&#x430;&#x441;&#x441;&#x43D;&#x43E;, &#x43D;&#x43E; &#x43C;&#x44B; &#x440;&#x435;&#x448;&#x438;&#x43B;&#x438; &#x43F;&#x43E;&#x43F;&#x440;&#x43E;&#x431;&#x43E;&#x432;&#x430;&#x442;&#x44C; &#x432;&#x442;&#x43E;&#x440;&#x43E;&#x439; &#x432;&#x430;&#x440;&#x438;&#x430;&#x43D;&#x442;. &#x41D;&#x435; &#x437;&#x43D;&#x430;&#x44E;, &#x435;&#x441;&#x442;&#x44C; &#x43B;&#x438; &#x443; &#x432;&#x43E;&#x434;&#x438;&#x442;&#x435;&#x43B;&#x435;&#x439; X &#x43B;&#x438;&#x446;&#x435;&#x43D;&#x437;&#x438;&#x44F;, &#x43D;&#x43E; &#x43D;&#x430; &#x442;&#x43E;&#x442; &#x43C;&#x43E;&#x43C;&#x435;&#x43D;&#x442; &#x44D;&#x442;&#x43E; &#x43D;&#x435; &#x43E;&#x441;&#x43E;&#x431;&#x43E; &#x432;&#x43E;&#x43B;&#x43D;&#x43E;&#x432;&#x430;&#x43B;&#x43E;. &#x418;&#x442;&#x430;&#x43A;, &#x432;&#x44B;&#x437;&#x432;&#x430;&#x43B;&#x438;, &#x43F;&#x435;&#x440;&#x432;&#x44B;&#x439; &#x442;&#x430;&#x43A;&#x441;&#x438;&#x441;&#x442; &#x441;&#x43F;&#x443;&#x441;&#x442;&#x44F; 5 &#x43C;&#x438;&#x43D;&#x443;&#x442; &#x43E;&#x442;&#x43C;&#x435;&#x43D;&#x438;&#x43B; &#x437;&#x430;&#x43A;&#x430;&#x437;, &#x430; &#x432;&#x442;&#x43E;&#x440;&#x43E;&#x439; &#x43F;&#x440;&#x438;&#x435;&#x445;&#x430;&#x43B; &#x447;&#x435;&#x440;&#x435;&#x437; 8. &#x41C;&#x430;&#x448;&#x438;&#x43D;&#x430; &#x447;&#x438;&#x441;&#x442;&#x430;&#x44F;, &#x441; &#x43A;&#x43E;&#x43D;&#x434;&#x438;&#x446;&#x438;&#x43E;&#x43D;&#x435;&#x440;&#x43E;&#x43C;, &#x432;&#x43E;&#x434;&#x438;&#x442;&#x435;&#x43B;&#x44C; &#x43D;&#x435; &#x43C;&#x435;&#x448;&#x430;&#x435;&#x442; &#x441;&#x432;&#x43E;&#x435;&#x439; &#x43C;&#x443;&#x437;&#x44B;&#x43A;&#x43E;&#x439; &#x438; &#x441;&#x43D;&#x43E;&#x441;&#x43D;&#x43E; &#x43E;&#x431;&#x44A;&#x44F;&#x441;&#x43D;&#x44F;&#x435;&#x442;&#x441;&#x44F; &#x43F;&#x43E;-&#x430;&#x43D;&#x433;&#x43B;&#x438;&#x439;&#x441;&#x43A;&#x438;. &#x422;.&#x43A;. &#x432; &#x43F;&#x440;&#x438;&#x43B;&#x43E;&#x436;&#x435;&#x43D;&#x438;&#x438; &#x443;&#x436;&#x435; &#x432;&#x44B;&#x431;&#x440;&#x430;&#x43D;&#x430; &#x442;&#x43E;&#x447;&#x43A;&#x430; &#x43D;&#x430;&#x437;&#x43D;&#x430;&#x447;&#x435;&#x43D;&#x438;&#x44F;, &#x43E;&#x431;&#x44A;&#x44F;&#x441;&#x43D;&#x44F;&#x442;&#x44C; &#x435;&#x43C;&#x443; &#x43A;&#x430;&#x43A; &#x435;&#x445;&#x430;&#x442;&#x44C; &#x43D;&#x435; &#x43D;&#x430;&#x434;&#x43E;, Google &#x44D;&#x442;&#x43E; &#x441;&#x434;&#x435;&#x43B;&#x430;&#x43B; &#x437;&#x430; &#x43D;&#x430;&#x441;.</p>
<p>&#x41A; &#x441;&#x43B;&#x43E;&#x432;&#x443;, &#x435;&#x445;&#x430;&#x442;&#x44C; &#x438;&#x437; &#x430;&#x44D;&#x440;&#x43E;&#x43F;&#x43E;&#x440;&#x442;&#x430; &#x434;&#x43E; &#x446;&#x435;&#x43D;&#x442;&#x440;&#x430; &#x433;&#x43E;&#x440;&#x43E;&#x434;&#x430; ~ 1 &#x447;&#x430;&#x441; &#x438; 25 &#x43A;&#x43C; (&#x434;&#x43E; &#x43D;&#x430;&#x448;&#x435;&#x433;&#x43E; &#x43E;&#x442;&#x435;&#x43B;&#x44F;). &#x417;&#x430; &#x432;&#x441;&#x435; &#x2014; $8. &#x42D;&#x442;&#x430; &#x441;&#x443;&#x43C;&#x43C;&#x430; &#x441;&#x43D;&#x438;&#x43C;&#x430;&#x435;&#x442;&#x441;&#x44F; &#x441; &#x43F;&#x440;&#x438;&#x432;&#x44F;&#x437;&#x430;&#x43D;&#x43D;&#x43E;&#x439; &#x43A;&#x430;&#x440;&#x442;&#x44B;, &#x43D;&#x430;&#x43B;&#x438;&#x447;&#x43A;&#x430; &#x43D;&#x435; &#x43D;&#x443;&#x436;&#x43D;&#x430;. &#x41D;&#x430; &#x432;&#x440;&#x435;&#x43C;&#x44F; &#x43F;&#x443;&#x442;&#x435;&#x448;&#x435;&#x441;&#x442;&#x432;&#x438;&#x439; &#x43C;&#x44B; &#x43F;&#x43E;&#x441;&#x442;&#x430;&#x440;&#x430;&#x43B;&#x438;&#x441;&#x44C; &#x43E;&#x442;&#x441;&#x442;&#x440;&#x430;&#x43D;&#x438;&#x442;&#x44C;&#x441;&#x44F; &#x43E;&#x442; &#x442;&#x435;&#x43A;&#x443;&#x449;&#x435;&#x433;&#x43E; &#x43A;&#x443;&#x440;&#x441;&#x430; &#x434;&#x43E;&#x43B;&#x43B;&#x430;&#x440;&#x430; &#x438; &#x434;&#x443;&#x43C;&#x430;&#x442;&#x44C; &#x43E; &#x446;&#x435;&#x43D;&#x430;&#x445; &#x438;&#x43C;&#x435;&#x43D;&#x43D;&#x43E; &#x432; &#x437;&#x435;&#x43B;&#x435;&#x43D;&#x43E;&#x439; &#x432;&#x430;&#x43B;&#x44E;&#x442;&#x435;. &#x42D;&#x442;&#x43E; &#x434;&#x435;&#x448;&#x435;&#x432;&#x43E;, &#x441;&#x435;&#x440;&#x44C;&#x435;&#x437;&#x43D;&#x43E;, &#x43E;&#x447;&#x435;&#x43D;&#x44C;s &#x434;&#x435;&#x448;&#x435;&#x432;&#x43E;.</p>
<p>&#x41D;&#x430;&#x447;&#x438;&#x43D;&#x430;&#x44F; &#x441; &#x44D;&#x442;&#x43E;&#x433;&#x43E; &#x43C;&#x43E;&#x43C;&#x435;&#x43D;&#x442;&#x430; &#x438; &#x434;&#x43E; &#x441;&#x430;&#x43C;&#x43E;&#x433;&#x43E; &#x43A;&#x43E;&#x43D;&#x446;&#x430; &#x43F;&#x443;&#x442;&#x435;&#x448;&#x435;&#x441;&#x442;&#x432;&#x438;&#x44F;, &#x43C;&#x44B; &#x43F;&#x43E;&#x43B;&#x44C;&#x437;&#x43E;&#x432;&#x430;&#x43B;&#x438;&#x441;&#x44C; &#x442;&#x43E;&#x43B;&#x44C;&#x43A;&#x43E; Uber. &#x41F;&#x440;&#x430;&#x432;&#x434;&#x430; &#x43D;&#x435; &#x432;&#x43E; &#x432;&#x441;&#x435;&#x445; &#x433;&#x43E;&#x440;&#x43E;&#x434;&#x430;&#x445; &#x43E;&#x43D; &#x431;&#x44B;&#x43B; :(</p>
<p>&#x414;&#x43E;&#x43F;&#x43E;&#x43B;&#x43D;&#x438;&#x442;&#x435;&#x43B;&#x44C;&#x43D;&#x44B;&#x435; &#x442;&#x440;&#x430;&#x442;&#x44B; &#x432;&#x43E;&#x434;&#x438;&#x442;&#x435;&#x43B;&#x44F; &#x442;&#x430;&#x43A;&#x436;&#x435; &#x432;&#x43D;&#x43E;&#x441;&#x44F;&#x442;&#x441;&#x44F; &#x432; &#x441;&#x447;&#x435;&#x442;. &#x42D;&#x442;&#x43E; &#x443;&#x434;&#x43E;&#x431;&#x43D;&#x43E;, &#x43F;&#x43E;&#x442;&#x43E;&#x43C;&#x443; &#x447;&#x442;&#x43E; &#x432; &#x425;&#x430;&#x43D;&#x43E;&#x435;, &#x43D;&#x430;&#x43F;&#x440;&#x438;&#x43C;&#x435;&#x440;, &#x432;&#x44A;&#x435;&#x437;&#x434; &#x432; &#x430;&#x44D;&#x440;&#x43E;&#x43F;&#x43E;&#x440;&#x442; &#x441;&#x442;&#x43E;&#x438;&#x442; 15000 &#x434;&#x43E;&#x43D;&#x433;&#x43E;&#x432; (&#x447;&#x443;&#x442;&#x44C; &#x43C;&#x435;&#x43D;&#x44C;&#x448;&#x435; $1) &#x438; &#x442;&#x435;&#x431;&#x435; &#x43D;&#x435; &#x43D;&#x430;&#x434;&#x43E; &#x438;&#x441;&#x43A;&#x430;&#x442;&#x44C; &#x43C;&#x435;&#x441;&#x442;&#x43D;&#x443;&#x44E; &#x43D;&#x430;&#x43B;&#x438;&#x447;&#x43A;&#x443; &#x438;&#x43B;&#x438; $1, &#x438;&#x445; &#x43F;&#x440;&#x43E;&#x441;&#x442;&#x43E; &#x441;&#x43F;&#x438;&#x448;&#x443;&#x442; &#x441; &#x43A;&#x430;&#x440;&#x442;&#x44B;.</p>
<p>&#x41D;&#x435;&#x43C;&#x43D;&#x43E;&#x433;&#x43E; &#x43E; &#x442;&#x435;&#x445;&#x43F;&#x43E;&#x434;&#x434;&#x435;&#x440;&#x436;&#x43A;&#x435;. &#x423;&#x435;&#x437;&#x436;&#x430;&#x43B;&#x438; &#x438;&#x437; &#x425;&#x430;&#x43D;&#x43E;&#x44F; &#x438; &#x432;&#x43E;&#x434;&#x438;&#x442;&#x435;&#x43B;&#x44C; &#x43F;&#x440;&#x438;&#x432;&#x435;&#x437; &#x43D;&#x430;&#x441; &#x43D;&#x435; &#x43A; &#x442;&#x43E;&#x43C;&#x443; &#x442;&#x435;&#x440;&#x43C;&#x438;&#x43D;&#x430;&#x43B;&#x443; (&#x43D;&#x443;&#x436;&#x435;&#x43D; &#x431;&#x44B;&#x43B; international, &#x430; &#x43F;&#x440;&#x438;&#x432;&#x435;&#x437;&#x43B;&#x438; &#x43A; domestic). &#x41F;&#x43B;&#x430;&#x442;&#x430; &#x443; &#x43A;&#x430;&#x436;&#x434;&#x43E;&#x433;&#x43E; &#x442;&#x435;&#x440;&#x43C;&#x438;&#x43D;&#x430;&#x43B;&#x430; &#x441;&#x432;&#x43E;&#x44F;. &#x421;&#x43F;&#x438;&#x441;&#x430;&#x43B;&#x438; &#x437;&#x430; &#x43E;&#x431;&#x430; &#x442;&#x435;&#x440;&#x43C;&#x438;&#x43D;&#x430;&#x43B;&#x430;. &#x420;&#x430;&#x434;&#x438; &#x438;&#x43D;&#x442;&#x435;&#x440;&#x435;&#x441;&#x430;, &#x43E;&#x431;&#x440;&#x430;&#x442;&#x438;&#x43B;&#x441;&#x44F; &#x432; &#x43F;&#x43E;&#x434;&#x434;&#x435;&#x440;&#x436;&#x43A;&#x443; &#x438; &#x43F;&#x43E;&#x43F;&#x440;&#x43E;&#x441;&#x438;&#x43B; &#x43E;&#x442;&#x43A;&#x43E;&#x440;&#x440;&#x435;&#x43A;&#x442;&#x438;&#x440;&#x43E;&#x432;&#x430;&#x442;&#x44C; &#x441;&#x447;&#x435;&#x442;, &#x443;&#x43A;&#x430;&#x437;&#x430;&#x432; &#x447;&#x442;&#x43E; &#x432;&#x43E;&#x434;&#x438;&#x442;&#x435;&#x43B;&#x44C; &#x43E;&#x448;&#x438;&#x431;&#x441;&#x44F;. &#x412; &#x442;&#x435;&#x447;&#x435;&#x43D;&#x438;&#x435; 1 &#x434;&#x43D;&#x44F; &#x43F;&#x43E;&#x434;&#x434;&#x435;&#x440;&#x436;&#x43A;&#x430; &#x43E;&#x442;&#x43F;&#x438;&#x441;&#x430;&#x43B;&#x430;&#x441;&#x44C;, &#x447;&#x442;&#x43E; &#x434;&#x435;&#x439;&#x441;&#x442;&#x432;&#x438;&#x442;&#x435;&#x43B;&#x44C;&#x43D;&#x43E; &#x432;&#x43E;&#x434;&#x438;&#x442;&#x435;&#x43B;&#x44C; &#x43E;&#x448;&#x438;&#x431;&#x441;&#x44F; &#x438; &#x441;&#x440;&#x435;&#x434;&#x441;&#x442;&#x432;&#x430; &#x437;&#x430; &#x432;&#x44A;&#x435;&#x437;&#x434; &#x43D;&#x430; &#x43E;&#x434;&#x438;&#x43D; &#x438;&#x437; &#x442;&#x435;&#x440;&#x43C;&#x438;&#x43D;&#x430;&#x43B;&#x43E;&#x432; &#x432;&#x435;&#x440;&#x43D;&#x443;&#x43B;&#x438; &#x43D;&#x430; &#x43A;&#x430;&#x440;&#x442;&#x443;.</p>
<p>&#x421;&#x43B;&#x435;&#x434;&#x443;&#x44E;&#x449;&#x435;&#x439; &#x43D;&#x430;&#x448;&#x435;&#x439; &#x442;&#x43E;&#x447;&#x43A;&#x43E;&#x439; &#x431;&#x44B;&#x43B; &#x41A;&#x443;&#x430;&#x43B;&#x430; &#x41B;&#x443;&#x43C;&#x43F;&#x443;&#x440;, &#x438; &#x442;&#x430;&#x43C; &#x43C;&#x44B; &#x442;&#x43E;&#x436;&#x435; &#x43F;&#x43E;&#x43B;&#x44C;&#x437;&#x43E;&#x432;&#x430;&#x43B;&#x438;&#x441;&#x44C; Uber. &#x418;&#x437; &#x430;&#x44D;&#x440;&#x43E;&#x43F;&#x43E;&#x440;&#x442;&#x430; &#x431;&#x440;&#x430;&#x442;&#x44C; &#x43D;&#x435; &#x441;&#x442;&#x430;&#x43B;&#x438;, &#x442;.&#x43A;. &#x43E;&#x447;&#x435;&#x43D;&#x44C; &#x431;&#x43E;&#x43B;&#x44C;&#x448;&#x438;&#x435; &#x43F;&#x440;&#x43E;&#x431;&#x43A;&#x438; &#x432; &#x433;&#x43E;&#x440;&#x43E;&#x434;&#x435; &#x438; &#x431;&#x44B;&#x441;&#x442;&#x440;&#x435;&#x435; &#x434;&#x43E;&#x431;&#x440;&#x430;&#x442;&#x44C;&#x441;&#x44F; &#x43D;&#x430; &#x43C;&#x435;&#x441;&#x442;&#x43D;&#x43E;&#x43C; &#x430;&#x44D;&#x440;&#x43E;&#x44D;&#x43A;&#x441;&#x43F;&#x440;&#x435;&#x441;&#x441;&#x435;, &#x430; &#x443;&#x436;&#x435; &#x432; &#x433;&#x43E;&#x440;&#x43E;&#x434;&#x435; &#x437;&#x430; &#x43F;&#x430;&#x440;&#x443; &#x434;&#x43E;&#x43B;&#x43B;&#x430;&#x440;&#x43E;&#x432; &#x434;&#x43E;&#x431;&#x440;&#x430;&#x442;&#x44C;&#x441;&#x44F; &#x434;&#x43E; &#x43E;&#x442;&#x435;&#x43B;&#x44F;. &#x41D;&#x430; Uber X &#x447;&#x435;&#x440;&#x435;&#x437; &#x432;&#x435;&#x441;&#x44C; &#x433;&#x43E;&#x440;&#x43E;&#x434; &#x441; &#x43F;&#x440;&#x43E;&#x431;&#x43A;&#x430;&#x43C;&#x438; &#x43C;&#x44B; &#x43E;&#x434;&#x43D;&#x430;&#x436;&#x434;&#x44B; &#x43F;&#x440;&#x43E;&#x435;&#x445;&#x430;&#x43B;&#x438; &#x437;&#x430; $7. &#x411;&#x438;&#x437;&#x43D;&#x435;&#x441; &#x43B;&#x430;&#x43D;&#x447; &#x432; &#x41A;&#x443;&#x430;&#x43B;&#x430; &#x41B;&#x443;&#x43C;&#x43F;&#x443;&#x440;&#x435; &#x441;&#x442;&#x43E;&#x438;&#x442; &#x434;&#x43E;&#x440;&#x43E;&#x436;&#x435;. &#x41D;&#x438; &#x440;&#x430;&#x437;&#x443; &#x43D;&#x435; &#x43F;&#x43E;&#x43B;&#x44C;&#x437;&#x43E;&#x432;&#x430;&#x43B;&#x438;&#x441;&#x44C; &#x43E;&#x431;&#x449;&#x435;&#x441;&#x442;&#x432;&#x435;&#x43D;&#x43D;&#x44B;&#x43C; &#x442;&#x440;&#x430;&#x43D;&#x441;&#x43F;&#x43E;&#x440;&#x442;&#x43E;&#x43C;. &#x41E;&#x441;&#x442;&#x430;&#x43D;&#x43E;&#x432;&#x43A;&#x438; &#x43D;&#x430;&#x445;&#x43E;&#x434;&#x44F;&#x442;&#x441;&#x44F; &#x43D;&#x430; &#x431;&#x43E;&#x43B;&#x44C;&#x448;&#x438;&#x445; &#x440;&#x430;&#x441;&#x441;&#x442;&#x43E;&#x44F;&#x43D;&#x438;&#x44F;&#x445;, &#x430; &#x43D;&#x430; &#x443;&#x43B;&#x438;&#x446;&#x435; +30 &#x433;&#x440;&#x430;&#x434;&#x443;&#x441;&#x43E;&#x432;. &#x41F;&#x440;&#x43E;&#x435;&#x437;&#x434; &#x43D;&#x430; &#x434;&#x432;&#x43E;&#x438;&#x445; &#x441;&#x442;&#x43E;&#x438;&#x442; &#x43F;&#x440;&#x438;&#x43C;&#x435;&#x440;&#x43D;&#x43E; &#x43A;&#x430;&#x43A; &#x442;&#x430;&#x43A;&#x441;&#x438;, &#x442;&#x430;&#x43A; &#x447;&#x442;&#x43E; &#x432;&#x44B;&#x431;&#x43E;&#x440; &#x43E;&#x447;&#x435;&#x432;&#x438;&#x434;&#x435;&#x43D;.</p>
<p><em>&#x420;&#x435;&#x437;&#x44E;&#x43C;&#x435;</em>. &#x422;&#x430;&#x43C; &#x433;&#x434;&#x435; &#x435;&#x441;&#x442;&#x44C; Uber &#x2014; &#x438;&#x43C; &#x440;&#x435;&#x430;&#x43B;&#x44C;&#x43D;&#x43E; &#x441;&#x442;&#x43E;&#x438;&#x442; &#x43F;&#x43E;&#x43B;&#x44C;&#x437;&#x43E;&#x432;&#x430;&#x442;&#x44C;&#x441;&#x44F;. &#x41F;&#x440;&#x43E;&#x432;&#x435;&#x440;&#x435;&#x43D;&#x43E; &#x43D;&#x430; &#x441;&#x43E;&#x431;&#x441;&#x442;&#x432;&#x435;&#x43D;&#x43D;&#x43E;&#x43C; &#x43E;&#x43F;&#x44B;&#x442;&#x435;.</p>
<p><em>P.S.</em> &#x41A;&#x443;&#x434;&#x430; &#x436;&#x435; &#x431;&#x435;&#x437; &#x440;&#x435;&#x444;&#x435;&#x440;&#x430;&#x43B;&#x44C;&#x43D;&#x43E;&#x439; &#x441;&#x441;&#x44B;&#x43B;&#x43A;&#x438;: <a href="https://www.uber.com/invite/p8ufd?ref=igkuz.ru">&#x431;&#x435;&#x441;&#x43F;&#x43B;&#x430;&#x442;&#x43D;&#x430;&#x44F; &#x43F;&#x43E;&#x435;&#x437;&#x434;&#x43A;&#x430; &#x434;&#x43B;&#x44F; &#x442;&#x435;&#x431;&#x44F; &#x438; &#x43C;&#x435;&#x43D;&#x44F;</a>.</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[[Отзыв]: Искусство войны]]></title><description><![CDATA[управление компанией, искусство войны, управление]]></description><link>https://igkuz.ru/otzyv-iskusstvo-voiny/</link><guid isPermaLink="false">5e9209026d9007355d8bde4b</guid><category><![CDATA[книги]]></category><category><![CDATA[отзыв]]></category><dc:creator><![CDATA[Igor Kuznetsov]]></dc:creator><pubDate>Tue, 15 Sep 2015 15:51:14 GMT</pubDate><media:content url="https://igkuz.ru/content/images/2015/09/1007255953.jpg" medium="image"/><content:encoded><![CDATA[<!--kg-card-begin: markdown--><img src="https://igkuz.ru/content/images/2015/09/1007255953.jpg" alt="[&#x41E;&#x442;&#x437;&#x44B;&#x432;]: &#x418;&#x441;&#x43A;&#x443;&#x441;&#x441;&#x442;&#x432;&#x43E; &#x432;&#x43E;&#x439;&#x43D;&#x44B;"><p>&#x41D;&#x430;&#x448;&#x435;&#x43B; &#x44D;&#x442;&#x443; &#x43A;&#x43D;&#x438;&#x433;&#x443; &#x432; &#x43E;&#x434;&#x43D;&#x43E;&#x43C; &#x438;&#x437; &#x43C;&#x43D;&#x43E;&#x433;&#x43E;&#x447;&#x438;&#x441;&#x43B;&#x435;&#x43D;&#x43D;&#x44B;&#x445; &#x441;&#x43F;&#x438;&#x441;&#x43A;&#x43E;&#x432; &quot;&#x43A;&#x43D;&#x438;&#x433; &#x43E;&#x431;&#x44F;&#x437;&#x430;&#x442;&#x435;&#x43B;&#x44C;&#x43D;&#x44B;&#x445; &#x43A; &#x43F;&#x440;&#x43E;&#x447;&#x442;&#x435;&#x43D;&#x438;&#x44E;&quot;. &#x41D;&#x430;&#x434;&#x43E; &#x441;&#x43A;&#x430;&#x437;&#x430;&#x442;&#x44C;, &#x43D;&#x438; &#x440;&#x430;&#x437;&#x443; &#x43D;&#x435; &#x43F;&#x43E;&#x436;&#x430;&#x43B;&#x435;&#x43B;.</p>
<p>&#x42D;&#x442;&#x43E; &#x447;&#x442;&#x43E;-&#x442;&#x43E; &#x432;&#x440;&#x43E;&#x434;&#x435; &#x442;&#x440;&#x430;&#x43A;&#x442;&#x430;&#x442;&#x430; &#x43E; &#x432;&#x435;&#x434;&#x435;&#x43D;&#x438;&#x438; &#x432;&#x43E;&#x435;&#x43D;&#x43D;&#x44B;&#x445; &#x434;&#x435;&#x439;&#x441;&#x442;&#x432;&#x438;&#x439;. &#x421;&#x430;&#x43C;&#x43E; &#x43F;&#x43E; &#x441;&#x435;&#x431;&#x435; &#x43F;&#x440;&#x43E;&#x438;&#x437;&#x432;&#x435;&#x434;&#x435;&#x43D;&#x438;&#x435; &#x43C;&#x430;&#x43B;&#x435;&#x43D;&#x44C;&#x43A;&#x43E;&#x435;, &#x43D;&#x43E; &#x43E;&#x447;&#x435;&#x43D;&#x44C; &#x431;&#x43E;&#x43B;&#x44C;&#x448;&#x438;&#x435; &#x43F;&#x440;&#x438;&#x43C;&#x435;&#x447;&#x430;&#x43D;&#x438;&#x44F; &#x43F;&#x435;&#x440;&#x435;&#x432;&#x43E;&#x434;&#x447;&#x438;&#x43A;&#x430;. &#x44D;&#x442;&#x438; &#x43F;&#x440;&#x438;&#x43C;&#x435;&#x447;&#x430;&#x43D;&#x438;&#x44F; &#x438;&#x43D;&#x43E;&#x433;&#x434;&#x430; &#x438;&#x43D;&#x442;&#x435;&#x440;&#x435;&#x441;&#x43D;&#x435;&#x435; &#x441;&#x430;&#x43C;&#x43E;&#x433;&#x43E; &#x442;&#x440;&#x430;&#x43A;&#x442;&#x430;&#x442;&#x430;. &#x422;&#x430;&#x43C; &#x443;&#x43F;&#x43E;&#x43C;&#x438;&#x43D;&#x430;&#x44E;&#x442;&#x441;&#x44F; &#x438;&#x441;&#x442;&#x43E;&#x440;&#x438;&#x447;&#x435;&#x441;&#x43A;&#x438;&#x435; &#x441;&#x43E;&#x431;&#x44B;&#x442;&#x438;&#x44F;, &#x43A;&#x430;&#x43A; &#x442;&#x443; &#x438;&#x43B;&#x438; &#x438;&#x43D;&#x443;&#x44E; &#x444;&#x440;&#x430;&#x437;&#x443; &#x43F;&#x435;&#x440;&#x435;&#x432;&#x43E;&#x434;&#x438;&#x43B;&#x438; &#x434;&#x440;&#x443;&#x433;&#x438;&#x435; &#x440;&#x435;&#x434;&#x430;&#x43A;&#x442;&#x43E;&#x440;&#x44B; &#x438; &#x43F;&#x43E;&#x447;&#x435;&#x43C;&#x443; &#x441;&#x430;&#x43C; &#x43F;&#x435;&#x440;&#x435;&#x432;&#x43E;&#x434;&#x447;&#x438;&#x43A; &#x432;&#x44B;&#x431;&#x440;&#x430;&#x43B; &#x442;&#x43E;&#x442; &#x438;&#x43B;&#x438; &#x438;&#x43D;&#x43E;&#x439; &#x441;&#x43C;&#x44B;&#x441;&#x43B; &#x438;&#x441;&#x445;&#x43E;&#x434;&#x44F; &#x438;&#x437; &#x434;&#x430;&#x43D;&#x43D;&#x43E;&#x433;&#x43E; &#x43A;&#x43E;&#x43D;&#x442;&#x435;&#x43A;&#x441;&#x442;&#x430;.</p>
<p>&#x412;&#x435;&#x440;&#x43D;&#x435;&#x43C;&#x441;&#x44F; &#x43A; &#x441;&#x430;&#x43C;&#x43E;&#x43C;&#x443; &#x442;&#x435;&#x43A;&#x441;&#x442;&#x443;. &#x41E;&#x431;&#x44B;&#x447;&#x43D;&#x44B;&#x435; &#x436;&#x438;&#x442;&#x435;&#x43B;&#x438; &#x441;&#x442;&#x440;&#x430;&#x43D;&#x44B; &#x441;&#x447;&#x438;&#x442;&#x430;&#x44E;&#x442; &#x432;&#x43E;&#x439;&#x43D;&#x43E;&#x439; &#x441;&#x438;&#x442;&#x443;&#x430;&#x446;&#x438;&#x44E; &#x43A;&#x43E;&#x433;&#x434;&#x430; &#x43F;&#x440;&#x43E;&#x438;&#x441;&#x445;&#x43E;&#x434;&#x44F;&#x442; &#x432;&#x44B;&#x441;&#x442;&#x440;&#x435;&#x43B;&#x44B; &#x438; &#x443;&#x43C;&#x438;&#x440;&#x430;&#x44E;&#x442; &#x43B;&#x44E;&#x434;&#x438;, &#x43D;&#x43E; &#x43D;&#x430; &#x441;&#x430;&#x43C;&#x43E;&#x43C; &#x434;&#x435;&#x43B;&#x435; &#x44D;&#x442;&#x43E; &#x43D;&#x435; &#x442;&#x430;&#x43A;. &#x421;&#x442;&#x440;&#x430;&#x43D;&#x430; &#x432;&#x441;&#x435;&#x433;&#x434;&#x430; &#x43D;&#x430;&#x445;&#x43E;&#x434;&#x438;&#x442;&#x441;&#x44F; &#x432; &#x441;&#x43E;&#x441;&#x442;&#x43E;&#x44F;&#x43D;&#x438;&#x438; &#x432;&#x43E;&#x439;&#x43D;&#x44B;, &#x43F;&#x440;&#x43E;&#x441;&#x442;&#x43E; &#x435;&#x441;&#x442;&#x44C; &#x440;&#x430;&#x437;&#x43D;&#x44B;&#x435; &#x443;&#x440;&#x43E;&#x432;&#x43D;&#x438; &#x43F;&#x440;&#x43E;&#x442;&#x438;&#x432;&#x43E;&#x441;&#x442;&#x43E;&#x44F;&#x43D;&#x438;&#x44F;. &#x412; &#x43F;&#x435;&#x440;&#x432;&#x443;&#x44E; &#x43E;&#x447;&#x435;&#x440;&#x435;&#x434;&#x44C; &#x43D;&#x430;&#x434;&#x43E; &#x440;&#x430;&#x437;&#x440;&#x443;&#x448;&#x430;&#x442;&#x44C; &#x43F;&#x43B;&#x430;&#x43D;&#x44B; &#x43F;&#x440;&#x43E;&#x442;&#x438;&#x432;&#x43D;&#x438;&#x43A;&#x430;, &#x43F;&#x43E;&#x441;&#x43B;&#x435; &#x441;&#x43E;&#x44E;&#x437;&#x44B;, &#x430; &#x435;&#x441;&#x43B;&#x438; &#x443;&#x436; &#x43D;&#x435; &#x43F;&#x43E;&#x43B;&#x443;&#x447;&#x430;&#x435;&#x442;&#x441;&#x44F; &#x43D;&#x438;&#x43A;&#x430;&#x43A; &#x43E;&#x431;&#x43E;&#x439;&#x442;&#x438;&#x441;&#x44C; &#x43C;&#x430;&#x43B;&#x43E;&#x439; &#x43A;&#x440;&#x43E;&#x432;&#x44C;&#x44E;, &#x442;&#x43E; &#x432;&#x441;&#x442;&#x443;&#x43F;&#x430;&#x442;&#x44C; &#x432; &#x444;&#x430;&#x437;&#x443; &#x430;&#x43A;&#x442;&#x438;&#x432;&#x43D;&#x44B;&#x445; &#x431;&#x43E;&#x435;&#x432;&#x44B;&#x445; &#x434;&#x435;&#x439;&#x441;&#x442;&#x432;&#x438;&#x439;.</p>
<p>&#x418;&#x43C;&#x43F;&#x43E;&#x43D;&#x438;&#x440;&#x443;&#x435;&#x442; &#x441;&#x430;&#x43C;&#x430;&#x44F; &#x43F;&#x435;&#x440;&#x432;&#x430;&#x44F; &#x433;&#x43B;&#x430;&#x432;&#x430;, &#x432; &#x43A;&#x43E;&#x442;&#x43E;&#x440;&#x43E;&#x439; &#x430;&#x432;&#x442;&#x43E;&#x440; &#x440;&#x430;&#x441;&#x441;&#x43A;&#x430;&#x437;&#x44B;&#x432;&#x430;&#x435;&#x442; &#x43E; &#x431;&#x430;&#x437;&#x43E;&#x432;&#x44B;&#x445; &#x432;&#x435;&#x449;&#x430;&#x445; - &#x43E;&#x441;&#x43D;&#x43E;&#x432;&#x430;&#x445; &#x43F;&#x43E;&#x441;&#x442;&#x440;&#x43E;&#x435;&#x43D;&#x438;&#x44F; &#x430;&#x440;&#x43C;&#x438;&#x438; &#x438; &#x432;&#x435;&#x434;&#x435;&#x43D;&#x438;&#x44F; &#x431;&#x43E;&#x435;&#x432;&#x44B;&#x445; &#x434;&#x435;&#x439;&#x441;&#x442;&#x432;&#x438;&#x439;. &#x41D;&#x430;&#x447;&#x438;&#x43D;&#x430;&#x435;&#x442;&#x441;&#x44F; &#x432;&#x441;&#x435; &#x441; &#x43F;&#x440;&#x430;&#x432;&#x438;&#x43B;&#x44C;&#x43D;&#x43E;&#x433;&#x43E; &#x43F;&#x43E;&#x441;&#x44B;&#x43B;&#x430;, &#x43F;&#x440;&#x430;&#x432;&#x438;&#x442;&#x435;&#x43B;&#x44C; &#x434;&#x43E;&#x43B;&#x436;&#x435;&#x43D; &#x440;&#x443;&#x43A;&#x43E;&#x432;&#x43E;&#x434;&#x438;&#x442;&#x44C; &#x441;&#x432;&#x43E;&#x438;&#x43C; &#x43D;&#x430;&#x440;&#x43E;&#x434;&#x43E;&#x43C; &#x442;&#x430;&#x43A;, &#x447;&#x442;&#x43E;&#x431;&#x44B; &#x43D;&#x430;&#x440;&#x43E;&#x434; &#x433;&#x43E;&#x442;&#x43E;&#x432; &#x431;&#x44B;&#x43B; &#x437;&#x430; &#x43D;&#x435;&#x433;&#x43E; &#x441;&#x440;&#x430;&#x436;&#x430;&#x442;&#x44C;&#x441;&#x44F; &#x438; &#x443;&#x43C;&#x435;&#x440;&#x435;&#x442;&#x44C;. &#x412;&#x43E;&#x438;&#x43D;&#x44B; &#x434;&#x43E;&#x43B;&#x436;&#x43D;&#x44B; &#x437;&#x43D;&#x430;&#x442;&#x44C;, &#x447;&#x442;&#x43E; &#x43E;&#x43D;&#x438; &#x437;&#x430;&#x449;&#x438;&#x449;&#x430;&#x44E;&#x442; &#x441;&#x432;&#x43E;&#x44E; &#x441;&#x435;&#x43C;&#x44C;&#x44E; &#x438; &#x441;&#x432;&#x43E;&#x438;&#x445; &#x433;&#x440;&#x430;&#x436;&#x434;&#x430;&#x43D; &#x43E;&#x442; &#x431;&#x435;&#x434;&#x44B;, &#x430; &#x43D;&#x435; &#x43F;&#x43E;&#x432;&#x438;&#x43D;&#x443;&#x44E;&#x442;&#x441;&#x44F; &#x43F;&#x440;&#x438;&#x445;&#x43E;&#x442;&#x438; &#x432;&#x437;&#x431;&#x430;&#x43B;&#x430;&#x43C;&#x43E;&#x448;&#x43D;&#x43E;&#x433;&#x43E; &#x43F;&#x440;&#x430;&#x432;&#x438;&#x442;&#x435;&#x43B;&#x44F;.</p>
<p>&#x410; &#x442;&#x435;&#x43F;&#x435;&#x440;&#x44C; &#x441;&#x430;&#x43C;&#x43E;&#x435; &#x433;&#x43B;&#x430;&#x432;&#x43D;&#x43E;&#x435; &#x2014; &#x432;&#x441;&#x435; &#x44D;&#x442;&#x43E; &#x43E;&#x447;&#x435;&#x43D;&#x44C; &#x43A;&#x43B;&#x430;&#x441;&#x441;&#x43D;&#x43E; &#x43B;&#x43E;&#x436;&#x438;&#x442;&#x441;&#x44F; &#x43D;&#x430; &#x443;&#x43F;&#x440;&#x430;&#x432;&#x43B;&#x435;&#x43D;&#x438;&#x435; &#x431;&#x43E;&#x43B;&#x44C;&#x448;&#x43E;&#x439; &#x43A;&#x43E;&#x43C;&#x43F;&#x430;&#x43D;&#x438;&#x435;&#x439;.</p>
<p>&#x420;&#x435;&#x437;&#x44E;&#x43C;&#x435; &#x2014; &#x43E;&#x431;&#x44F;&#x437;&#x430;&#x442;&#x435;&#x43B;&#x44C;&#x43D;&#x43E; &#x43A; &#x43F;&#x440;&#x43E;&#x447;&#x442;&#x435;&#x43D;&#x438;&#x44E;.</p>
<table border="0" cellpadding="0" cellspacing="0"><tr><td width="70" valign="top"><a href="http://www.ozon.ru/context/detail/id/23145902/?partner=igkuz_blog&amp;from=bar&amp;ref=igkuz.ru" title="&#x41A;&#x43D;&#x438;&#x433;&#x430; &quot;&#x418;&#x441;&#x43A;&#x443;&#x441;&#x441;&#x442;&#x432;&#x43E; &#x432;&#x43E;&#x439;&#x43D;&#x44B;&quot; &#x421;&#x443;&#x43D;&#x44C;-&#x426;&#x437;&#x44B; - The Art of War ISBN 978-5-9910-2473-0"><img style="width: 60px; margin-right: 10px; border: 0;" src="//mmedia.ozone.ru/multimedia/books_covers/c300/1007255953.jpg" alt="[&#x41E;&#x442;&#x437;&#x44B;&#x432;]: &#x418;&#x441;&#x43A;&#x443;&#x441;&#x441;&#x442;&#x432;&#x43E; &#x432;&#x43E;&#x439;&#x43D;&#x44B;"></a></td><td style="vertical-align: middle;"><a style="color: black" title="&#x41A;&#x43D;&#x438;&#x433;&#x430; &quot;&#x418;&#x441;&#x43A;&#x443;&#x441;&#x441;&#x442;&#x432;&#x43E; &#x432;&#x43E;&#x439;&#x43D;&#x44B;&quot; &#x421;&#x443;&#x43D;&#x44C;-&#x426;&#x437;&#x44B; - The Art of War ISBN 978-5-9910-2473-0" href="http://www.ozon.ru/context/detail/id/23145902/?partner=igkuz_blog&amp;from=bar&amp;ref=igkuz.ru">&#x41A;&#x43D;&#x438;&#x433;&#x430; &quot;&#x418;&#x441;&#x43A;&#x443;&#x441;&#x441;&#x442;&#x432;&#x43E; &#x432;&#x43E;&#x439;&#x43D;&#x44B;&quot; &#x421;&#x443;&#x43D;&#x44C;-&#x426;&#x437;&#x44B; - The Art of War ISBN 978-5-9910-2473-0</a></td></tr></table><!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[[Отзыв] Эффективные коммуникации]]></title><description><![CDATA[деловая переписка, отзыв, эффективные коммуникации]]></description><link>https://igkuz.ru/otzyv-effiektivnyie-kommunikatsii/</link><guid isPermaLink="false">5e9209026d9007355d8bde6f</guid><category><![CDATA[отзыв]]></category><category><![CDATA[книги]]></category><dc:creator><![CDATA[Igor Kuznetsov]]></dc:creator><pubDate>Thu, 10 Sep 2015 10:20:07 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>&#x412; &#x43F;&#x43E;&#x441;&#x43B;&#x435;&#x434;&#x43D;&#x435;&#x435; &#x432;&#x440;&#x435;&#x43C;&#x44F; &#x443; &#x43C;&#x435;&#x43D;&#x44F; &#x441;&#x442;&#x430;&#x43B;&#x43E; &#x43E;&#x447;&#x435;&#x43D;&#x44C; &#x43C;&#x43D;&#x43E;&#x433;&#x43E; &#x434;&#x435;&#x43B;&#x43E;&#x432;&#x43E;&#x439; &#x43F;&#x435;&#x440;&#x435;&#x43F;&#x438;&#x441;&#x43A;&#x438;. &#x412; &#x43E;&#x441;&#x43D;&#x43E;&#x432;&#x43D;&#x43E;&#x43C; &#x44D;&#x442;&#x43E; &#x44D;&#x43B;&#x435;&#x43A;&#x442;&#x440;&#x43E;&#x43D;&#x43D;&#x430;&#x44F; &#x43F;&#x43E;&#x447;&#x442;&#x430;, &#x43D;&#x43E; &#x447;&#x430;&#x441;&#x442;&#x43E; &#x434;&#x435;&#x43B;&#x430;&#x44E; &#x43F;&#x440;&#x435;&#x437;&#x435;&#x43D;&#x442;&#x430;&#x446;&#x438;&#x438; &#x43F;&#x440;&#x43E;&#x435;&#x43A;&#x442;&#x43E;&#x432; &#x438; &#x440;&#x430;&#x437;&#x43D;&#x43E;&#x433;&#x43E; &#x440;&#x43E;&#x434;&#x430; &#x43A;&#x43E;&#x43C;&#x43C;&#x435;&#x440;&#x447;&#x435;&#x441;&#x43A;&#x438;&#x435; &#x43F;&#x440;&#x435;&#x434;&#x43B;&#x43E;&#x436;&#x435;&#x43D;&#x438;&#x44F;. &#x418; &#x43A;&#x43E;&#x433;&#x434;&#x430; &#x43D;&#x430; &#x433;&#x43B;&#x430;&#x437;&#x430; &#x43F;&#x43E;&#x43F;&#x430;&#x43B;&#x430;&#x441;&#x44C; &#x44D;&#x442;&#x430; &#x43A;&#x43D;&#x438;&#x433;&#x430;, &#x440;&#x435;&#x448;&#x438;&#x43B; &#x2014; &#x43D;&#x430;&#x434;&#x43E; &#x43F;&#x440;&#x43E;&#x447;&#x438;&#x442;&#x430;&#x442;&#x44C;.</p>
<p>&#x421; &#x43E;&#x434;&#x43D;&#x43E;&#x439; &#x441;&#x442;&#x43E;&#x440;&#x43E;&#x43D;&#x44B;, &#x442;&#x430;&#x43A;&#x438;&#x435; &#x43A;&#x43D;&#x438;&#x433;&#x438; &#x43C;&#x43E;&#x436;&#x43D;&#x43E; &#x43F;&#x440;&#x43E;&#x441;&#x43C;&#x430;&#x442;&#x440;&#x438;&#x432;&#x430;&#x442;&#x44C; &#x432; &#x43A;&#x440;&#x430;&#x442;&#x43A;&#x43E;&#x43C; &#x438;&#x437;&#x43B;&#x43E;&#x436;&#x435;&#x43D;&#x438;&#x438; &#x438; &#x43D;&#x435; &#x442;&#x440;&#x430;&#x442;&#x438;&#x442;&#x44C; &#x432;&#x440;&#x435;&#x43C;&#x44F; &#x43D;&#x430; &#x43F;&#x43E;&#x43B;&#x43D;&#x443;&#x44E; &#x432;&#x435;&#x440;&#x441;&#x438;&#x44E;, &#x43D;&#x43E; &#x442;.&#x43A;. &#x44F; &#x432; &#x43E;&#x442;&#x43F;&#x443;&#x441;&#x43A;&#x435;, &#x442;&#x43E; &#x43C;&#x43E;&#x436;&#x43D;&#x43E; &#x441;&#x435;&#x431;&#x435; &#x43F;&#x43E;&#x437;&#x432;&#x43E;&#x43B;&#x438;&#x442;&#x44C; &#x43F;&#x43E;&#x442;&#x44E;&#x43B;&#x435;&#x43D;&#x438;&#x442;&#x44C;.</p>
<p>&#x415;&#x441;&#x43B;&#x438; &#x432;&#x44B; &#x445;&#x43E;&#x442;&#x44C; &#x440;&#x430;&#x437; &#x447;&#x438;&#x442;&#x430;&#x43B;&#x438; &#x43B;&#x438;&#x442;&#x435;&#x440;&#x430;&#x442;&#x443;&#x440;&#x443; &#x43F;&#x43E; &#x434;&#x435;&#x43B;&#x43E;&#x432;&#x43E;&#x439; &#x43F;&#x435;&#x440;&#x435;&#x43F;&#x438;&#x441;&#x43A;&#x435;, &#x442;&#x43E; &#x447;&#x435;&#x433;&#x43E;-&#x442;&#x43E; &#x43F;&#x440;&#x43E;&#x440;&#x44B;&#x432;&#x43D;&#x43E;&#x433;&#x43E; &#x438; &#x43A;&#x430;&#x440;&#x434;&#x438;&#x43D;&#x430;&#x43B;&#x44C;&#x43D;&#x43E; &#x43D;&#x43E;&#x432;&#x43E;&#x433;&#x43E; &#x442;&#x443;&#x442; &#x43D;&#x435; &#x43D;&#x430;&#x439;&#x434;&#x435;&#x442;&#x435;, &#x43E;&#x434;&#x43D;&#x430;&#x43A;&#x43E; &#x43B;&#x438;&#x448;&#x43D;&#x438;&#x439; &#x440;&#x430;&#x437; &#x441;&#x438;&#x441;&#x442;&#x435;&#x43C;&#x430;&#x442;&#x438;&#x437;&#x438;&#x440;&#x43E;&#x432;&#x430;&#x442;&#x44C; &#x434;&#x430;&#x43D;&#x43D;&#x44B;&#x435; &#x432;&#x441;&#x435;&#x433;&#x434;&#x430; &#x43F;&#x43E;&#x43B;&#x435;&#x437;&#x43D;&#x43E;.</p>
<p>&#x41A;&#x43D;&#x438;&#x433;&#x430; &#x43E;&#x447;&#x435;&#x43D;&#x44C; &#x445;&#x43E;&#x440;&#x43E;&#x448;&#x43E; &#x440;&#x430;&#x437;&#x434;&#x435;&#x43B;&#x435;&#x43D;&#x430; &#x43D;&#x430; &#x447;&#x430;&#x441;&#x442;&#x438; &#x438; &#x433;&#x43B;&#x430;&#x432;&#x44B;, &#x44F;&#x437;&#x44B;&#x43A; &#x43F;&#x440;&#x43E;&#x441;&#x442;&#x43E;&#x439; &#x438; &#x447;&#x438;&#x442;&#x430;&#x435;&#x442;&#x441;&#x44F; &#x43B;&#x435;&#x433;&#x43A;&#x43E;. &#x41E;&#x441;&#x438;&#x43B;&#x438;&#x43B; &#x435;&#x451; &#x432; &#x441;&#x430;&#x43C;&#x43E;&#x43B;&#x435;&#x442;&#x435; &#x447;&#x430;&#x441;&#x430; &#x437;&#x430; 3.</p>
<p>&#x414;&#x43B;&#x44F; &#x43C;&#x435;&#x43D;&#x44F;, &#x43E;&#x441;&#x43D;&#x43E;&#x432;&#x43D;&#x430;&#x44F; &#x446;&#x435;&#x43D;&#x43D;&#x43E;&#x441;&#x442;&#x44C; &#x43A;&#x43D;&#x438;&#x433;&#x438; &#x431;&#x44B;&#x43B;&#x430; &#x432; &#x442;&#x435;&#x43A;&#x441;&#x442;&#x430;&#x445;. &#x412; &#x43A;&#x430;&#x436;&#x434;&#x43E;&#x439; &#x433;&#x43B;&#x430;&#x432;&#x435; &#x43F;&#x440;&#x438;&#x432;&#x43E;&#x434;&#x438;&#x442;&#x441;&#x44F; <em>&#x43D;&#x435;&#x43F;&#x440;&#x430;&#x432;&#x438;&#x43B;&#x44C;&#x43D;&#x44B;&#x439;</em> &#x43E;&#x442;&#x440;&#x44B;&#x432;&#x43E;&#x43A; &#x438; &#x43A;&#x430;&#x43A; &#x435;&#x433;&#x43E; &#x438;&#x441;&#x43F;&#x440;&#x430;&#x432;&#x438;&#x43B;&#x438; &#x43D;&#x430; <em>&#x43F;&#x440;&#x430;&#x432;&#x438;&#x43B;&#x44C;&#x43D;&#x44B;&#x439;</em>. &#x42D;&#x442;&#x43E; &#x43E;&#x447;&#x435;&#x43D;&#x44C; &#x43F;&#x43E;&#x43B;&#x435;&#x437;&#x43D;&#x43E; &#x438; &#x43F;&#x43E;&#x437;&#x432;&#x43E;&#x43B;&#x44F;&#x435;&#x442; &#x43F;&#x43E;&#x442;&#x440;&#x435;&#x43D;&#x438;&#x440;&#x43E;&#x432;&#x430;&#x442;&#x44C;&#x441;&#x44F;.</p>
<p>&#x420;&#x435;&#x437;&#x44E;&#x43C;&#x438;&#x440;&#x443;&#x44F;, &#x43F;&#x438;&#x448;&#x438;&#x442;&#x435; &#x43F;&#x440;&#x43E;&#x441;&#x442;&#x43E; &#x438; &#x44F;&#x441;&#x43D;&#x43E;, &#x444;&#x43E;&#x43A;&#x443;&#x441;&#x438;&#x440;&#x443;&#x439;&#x442;&#x435;&#x441;&#x44C; &#x43D;&#x430; &#x441;&#x432;&#x43E;&#x435;&#x439; &#x446;&#x435;&#x43B;&#x438; &#x438; &#x442;&#x440;&#x435;&#x43D;&#x438;&#x440;&#x443;&#x439;&#x442;&#x435;&#x441;&#x44C;.</p>
<table border="0" cellpadding="0" cellspacing="0"><tr><td width="70" valign="top"><a href="http://www.ozon.ru/context/detail/id/27261622/?partner=igkuz_blog&amp;from=bar&amp;ref=igkuz.ru" title="&#x41A;&#x43D;&#x438;&#x433;&#x430; &quot;&#x42D;&#x444;&#x444;&#x435;&#x43A;&#x442;&#x438;&#x432;&#x43D;&#x44B;&#x435; &#x43F;&#x438;&#x441;&#x44C;&#x43C;&#x435;&#x43D;&#x43D;&#x44B;&#x435; &#x434;&#x435;&#x43B;&#x43E;&#x432;&#x44B;&#x435; &#x43A;&#x43E;&#x43C;&#x43C;&#x443;&#x43D;&#x438;&#x43A;&#x430;&#x446;&#x438;&#x438;&quot; &#x411;&#x440;&#x430;&#x439;&#x430;&#x43D; &#x413;&#x430;&#x440;&#x43D;&#x435;&#x440; - HBR Guide to Better Business Writing ISBN 978-5-91657-940-6"><img style="width: 60px; margin-right: 10px; border: 0;" src="//mmedia.ozone.ru/multimedia/books_covers/c300/1010116132.jpg" alt="&#x41A;&#x43D;&#x438;&#x433;&#x430; &quot;&#x42D;&#x444;&#x444;&#x435;&#x43A;&#x442;&#x438;&#x432;&#x43D;&#x44B;&#x435; &#x43F;&#x438;&#x441;&#x44C;&#x43C;&#x435;&#x43D;&#x43D;&#x44B;&#x435; &#x434;&#x435;&#x43B;&#x43E;&#x432;&#x44B;&#x435; &#x43A;&#x43E;&#x43C;&#x43C;&#x443;&#x43D;&#x438;&#x43A;&#x430;&#x446;&#x438;&#x438;&quot; &#x411;&#x440;&#x430;&#x439;&#x430;&#x43D; &#x413;&#x430;&#x440;&#x43D;&#x435;&#x440; - HBR Guide to Better Business Writing ISBN 978-5-91657-940-6"></a></td><td style="vertical-align: middle;"><a style="color: black" title="&#x41A;&#x43D;&#x438;&#x433;&#x430; &quot;&#x42D;&#x444;&#x444;&#x435;&#x43A;&#x442;&#x438;&#x432;&#x43D;&#x44B;&#x435; &#x43F;&#x438;&#x441;&#x44C;&#x43C;&#x435;&#x43D;&#x43D;&#x44B;&#x435; &#x434;&#x435;&#x43B;&#x43E;&#x432;&#x44B;&#x435; &#x43A;&#x43E;&#x43C;&#x43C;&#x443;&#x43D;&#x438;&#x43A;&#x430;&#x446;&#x438;&#x438;&quot; &#x411;&#x440;&#x430;&#x439;&#x430;&#x43D; &#x413;&#x430;&#x440;&#x43D;&#x435;&#x440; - HBR Guide to Better Business Writing ISBN 978-5-91657-940-6" href="http://www.ozon.ru/context/detail/id/27261622/?partner=igkuz_blog&amp;from=bar&amp;ref=igkuz.ru">&#x41A;&#x43D;&#x438;&#x433;&#x430; &quot;&#x42D;&#x444;&#x444;&#x435;&#x43A;&#x442;&#x438;&#x432;&#x43D;&#x44B;&#x435; &#x43F;&#x438;&#x441;&#x44C;&#x43C;&#x435;&#x43D;&#x43D;&#x44B;&#x435; &#x434;&#x435;&#x43B;&#x43E;&#x432;&#x44B;&#x435; &#x43A;&#x43E;&#x43C;&#x43C;&#x443;&#x43D;&#x438;&#x43A;&#x430;&#x446;&#x438;&#x438;&quot; &#x411;&#x440;&#x430;&#x439;&#x430;&#x43D; &#x413;&#x430;&#x440;&#x43D;&#x435;&#x440; - HBR Guide to Better Business Writing ISBN 978-5-91657-940-6</a></td></tr></table><!--kg-card-end: markdown-->]]></content:encoded></item></channel></rss>