<?xml version="1.0" encoding="UTF-8"?>

<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" >

  <channel>
    <title><![CDATA[Комментарии / Профиль scriptuoz]]></title>
    <link>https://habr.com/ru/users/scriptuoz/comments/</link>
    <description><![CDATA[Хабр: комментарии пользователя scriptuoz]]></description>
    <language>ru</language>
    <managingEditor>editor@habr.com</managingEditor>
    <generator>habr.com</generator>
    <pubDate>Wed, 06 May 2026 00:47:09 GMT</pubDate>
    
    
      <image>
        <link>https://habr.com/ru/</link>
        <url>https://habrastorage.org/webt/ym/el/wk/ymelwk3zy1gawz4nkejl_-ammtc.png</url>
        <title>Хабр</title>
      </image>
    

    
      

      
        
  
    <item>
      <title>09.12.2025 19:54:57 </title>
      <guid isPermaLink="true">https://habr.com/ru/articles/970304/#comment_29230062</guid>
      <link>https://habr.com/ru/articles/970304/#comment_29230062</link>
      <description><![CDATA[<p>я статью прочел и вижу, что в статье непонимание почему так происходит, а вот в комментарии выше, я подробно расскрыл по шагам почему так происходит. И что самое важное это поведение полностью соответствует описанному в спецификации языка. </p>]]></description>
      <pubDate>Tue, 09 Dec 2025 19:54:57 GMT</pubDate>
      <dc:creator><![CDATA[]]></dc:creator>
    </item>
  

  
    <item>
      <title>09.12.2025 19:41:04 </title>
      <guid isPermaLink="true">https://habr.com/ru/articles/970304/#comment_29230018</guid>
      <link>https://habr.com/ru/articles/970304/#comment_29230018</link>
      <description><![CDATA[<p>Вы путаете понятия. Есть спецификация языка, вы можете с ней ознакомиться по ссылке и в ней вы не найдете про "ссылку под капотом" потому что этого нет. Далее есть реализация, которая своим поведением полностью соответствует спецификации.  А вот далее произошло то что вы не разобрались в той реализации которую увидели в искодниках и решили, что есть какая то магия. Но магии нет, ссылка там по вполне очевидным причинам и эти причины не "под капотом передается указатель". В горутину читатель, либо в буфер канала передается не ссылка а копия значения, и это можно увидеть в исходниках если заглянуть чуть дальше на несколько строчек (см. memmove в функциях "отправки"). В chansend передается по указателю потому что мы должны получить значение переменной в момент "отправки значения" а не в момент вызова функции chansend, момент отправки происходит когда мы кладем значение отправляемое в канал либо на стек горутины-читателя, либо в буфер канала. И вот если бы мы в chansend передавали не ссылку а значение, то при блокировке горутины, например канал не готов принять (нет читателя или буфер заполнен) мы должны остановить выполнение и к моменту когда горутина разблокируется (появится читатель или место в буфере) переменная может быть изменена другими горутинами, но мы от нее ужа отвязались так как взяли значение а не ссылку и как результат мы положим на стек горутины-читателя или в буфер канала старое значение. И это будет нарушением спецификации языка, то есть то самое явление когда реализация не соответствует спецификации. Но, нам повезло, в go team достаточно хорошие инженеры, чтобы не допустить такой ошибки.<br><br>&gt; в ваших размышлениях отсутствует какое-либо логическое объяснение того почему переменная либо "замыкается" либо нет в зависимости от того прибавляется к ней ноль или нет.<br><br>В "моих размышлениях" есть не более чем указание на спецификацию языка, которой в данном случае поведение полностью соответствует. Вот если бы не соответствовало, то был бы повод в подозрении на баг, но в текущей ситуации поведение полностью соответствует спецификации. И пока все говорит лишь о том, что вы не разобрались в реализации с одной стороны и не прочитали спецификацию с другой. Поэтому для вас это выглядит странным<br><br>ну и по поводу вашего примера, я если честно даже не знаю как еще показать простейшее элементарное поведение<br><br>ch &lt;- i + 0<br>это 2 операции<br>сначала выполняется i + 0<br>значение кладется на стек (можно по другому сказать создается временная переменная в которой хранится значение операции i + 0)<br>далее выполняется ch &lt;- (та самая временная переменная) И уже в этот момент тут нет никакой переменной i, тут есть канал оператор отправки в канал и временная переменная в которой содержится значение предыдущей операции. Но продолжим и в момент когда эта операция может быть исполнена (напомню это либо есть читатель, либо есть место в буфере) передается значение той самой временной переменной и тут нет никакой переменной i здесь есть "временная переменная" результат предыдущей операции (i + 0)<br><br>в ситуации ch &lt;- i<br>есть только одна операция, передача в канал, и когда эта операция может быть выполнена (а это напомню либо есть читатель, либо есть место в буфере) берется значение из переменной i <br><br>Далее по поводу дизассемблированного кода, это кстати возможно даже лучше будет моих объяснений. Вот здесь <a href="https://godbolt.org/z/5dKKrnGxW" rel="noopener noreferrer nofollow">https://godbolt.org/z/5dKKrnGxW</a> предлагяю поиграться с разными значениями, попробуйте разные варианты <br>ch &lt;- i<br>ch &lt;- i + 0<br>ch &lt;- i + 1<br>ch &lt;- i + 2<br><br>вы увидете что во всех этих вариантах код разный  и даже варианты +0 +1 +2 различаются между собой. Но также вы увидите то о чем собственно я и говорю, что в случаях + 0, + 1, + 2 появляется дополнительная операция и результат этой операции используется уже в отправке в канал, а при отсутствии арифметической операции работа идет непосредственно с переменной.</p><p>ch &lt;- i <br>PCDATA  $1, $0</p><p>CALL    runtime.chansend1(SB)<br><br></p><p>ch &lt;- i + 0</p><p>MOVQ    (CX), CX</p><p>MOVQ    CX, command-line-arguments..autotmp_0+16(SP)</p><p>LEAQ    command-line-arguments..autotmp_0+16(SP), BX</p><p>PCDATA  $1, $0</p><p>CALL    runtime.chansend1(SB)<br><br></p><p>ch &lt;- i + 1</p><p>MOVQ    (CX), CX</p><p> INCQ    CX</p><p>MOVQ    CX, command-line-arguments..autotmp_0+16(SP)</p><p>LEAQ    command-line-arguments..autotmp_0+16(SP), BX</p><p>PCDATA  $1, $0</p><p>CALL    runtime.chansend1(SB)</p><p>ch &lt;- i + 2</p><p>MOVQ    (CX), CX</p><p>ADDQ    $2, CX</p><p>MOVQ    CX, command-line-arguments..autotmp_0+16(SP)</p><p>LEAQ    command-line-arguments..autotmp_0+16(SP), BX</p><p>PCDATA  $1, $0</p><p>CALL    runtime.chansend1(SB)</p><p>но лучше сами попробуйте, разные варианты, если дружите с ассемблером<br><br>&gt; какая функция "замкнула" переменную и "изменяет" её? вы о чём? внешняя её изменяет но не замыкает (т.к. переменная глобальная) а внутренняя замыкает но не изменяет<br><br>хм,  я честно говоря думал, что вы сможете сообразить, что это не полный пример а его основная часть, демонсрация поведения так сказать<br>Ну хорошо вот полный пример<br></p><pre><code>package main

import "fmt"

func main() {
	example()
}

func example() {
	var i = 0
	f := func() int {
		i = 15
		return i
	}

	fmt.Println(i*i + 15)  // 15
	fmt.Println(i*i + f()) // 240
}
</code></pre><p>переменная i здесь не глобальная, а локальная для функции example, функция которую мы присвоили переменной f замкнула переменую i и... ну а далее надеюсь вы помните, и возможно даже увидите сходство примеров, что здесь f() выполняется до того как будет выполнена арифметическая операция, так как если бы было иначе, то первым должно было бы выполниться умножение в соответствии с приоритетом <em> над <code>+</code> <br>но на всякий случай допишу - сходство примера здесь в том, что казалось бы на одной строчке кода, есть разные две операции имеющие разный приоритет выполнения, в этом примере функция выполнится до того как начнет выполняться арифметическая операция `</em>i * i + (значение временной переменной хранящее значение функции f)` так же и в вашем примере ch &lt;- i + 0 есть две совершенно разные операции, с разным приоритетом выполнения и арифметическая операция i + 0 будет выполнена первой и ее значение будет "записано во временную переменную" (сохранено на стек) и вот когда дело дойдет до кода `ch &lt;- ...` то здесь уже нет переменной <code>i</code> здесь есть "временная переменная хранящая полученное значение операции которая уже завершилась" (значение хранящееся на стеке)<br><br>Честно говоря если после такой попытки разжевать все до элементарных вещей вы по прежнему останетесь при своем, то я умываю руки :)</p>]]></description>
      <pubDate>Tue, 09 Dec 2025 19:41:04 GMT</pubDate>
      <dc:creator><![CDATA[]]></dc:creator>
    </item>
  

  
    <item>
      <title>06.12.2025 12:14:22 </title>
      <guid isPermaLink="true">https://habr.com/ru/articles/970304/#comment_29214764</guid>
      <link>https://habr.com/ru/articles/970304/#comment_29214764</link>
      <description><![CDATA[<p>Откуда информация про "под капотом передается указатель"?<br>Нет в спецификации такого<br>По ссылке написано:<br>"The channel expression must be of&nbsp;<a href="https://go.dev/ref/spec#Channel_types" rel="noopener noreferrer nofollow">channel type</a>, the channel direction must permit send operations, and the type of the value to be sent must be&nbsp;<a href="https://go.dev/ref/spec#Assignability" rel="noopener noreferrer nofollow">assignable</a>&nbsp;to the channel's element type."<br>То есть если переводить на текущий пример,то:<br>слева должна быть переменная типа chan&lt;- T или chan T а справа должны быть некие данные с типом T<br>то есть в текущем примере слева chan int справа должно быть что угодно с типом int это может быть переменная или не переменная<br>Далее i + 0 это не тип int это выражение, арифметическая операция, результатом который будет значение int, но само по себе выражение не имеет тип int, как если бы мы определил функцию sum(ia, b int) int и вызывали ее вместо i + 0 то функция не имеет тип int она имеет тип func(int, int) int и результатом вызова этой функции будет значение с типом int<br>и дальше Both the channel and the value expression are evaluated before communication begins. то есть любые выражения должны быть приведены к нужным типам, поэтому i + 0 вычисляется еще до того как вообще началось какая либо история с каналом, и результат этого вычисления помещается на стек во временную локальную переменную. Дальше, у нас слева chan int справа результат арифм. операции сохраненный в локальной переменной и имеющий тип int и вот теперь все готово к тому чтобы communication. begins. Но, мы не можем выполнить передачу, потому что канал еще не готов, нет читателя, либо буфер заполнен, поэтому горутина блокируется не выполнив эту операцию. И вот когда появился читатель либо освободился буфер, горутина разблокируется и операция осуществляется и в этот момент в буфер канала (для буферизированных) или на стек горутины (для небуферизированных) помещается <strong>копия</strong> значения передаваемого в канал.<br>Для случае когда у нас нет сложение переменной i + 0 все обстоит ровно по такому же принципу как описано в спецификации.<br>В этот момент мы имеет слева chan int а справа мы имеем переменную i типа int то есть все готово для того чтобы communication begins. Но, канал не. готов потому что нет читателя, либо буфер заполнен, поэтому горутина блокируется не выполнив эту операцию.<br>Далее когда произошло чтение из канала и освободилось место в буфере, горутина разблокируется и операция выполняется, то есть <strong>в этот момент</strong> берется значение переменной i и <strong>копируется</strong> в буфер (для буферизированных) или на стек горутины читающей (для небуферизированных) <br><br>Никаких упоминаний о "под капотом передается указатель" нет в спецификации<br><br>Вот еще небольшой пример на схожую тему<br></p><pre><code>    var i = 0
	f := func() int {
		i = 15
		return i
	}

	fmt.Println(i*i + 15) // 15
	fmt.Println(i*i + f()) // 240</code></pre><p>казалось бы сначала выполняется умножение и только потом сложение, но мы можем использовать в выражении только то что подходит по типу, а f() не подходит по типу, так как это не int это функция результатом выполнения который будет значение с типом int, поэтому прежде, чем приступить к разбору арифметической операции и ее вычислению, мы выполняем функцию, которая замкнула переменную i и изменяет ее внутри тела, поэтому когда дело дойдет до самой арифметической операции, то значение переменной i уже изменилось<br>точно также в примере из статьи, когда дело доходит до `ch &lt;-` там уже нет переменной i там есть результат выражения i + 0 сохраненный в локальную переменную, и поэтому никакое дальнейшее изменение i не влияет на то, что уйдет в канал</p>]]></description>
      <pubDate>Sat, 06 Dec 2025 12:14:22 GMT</pubDate>
      <dc:creator><![CDATA[]]></dc:creator>
    </item>
  

  
    <item>
      <title>05.12.2025 22:22:43 </title>
      <guid isPermaLink="true">https://habr.com/ru/articles/970304/#comment_29212976</guid>
      <link>https://habr.com/ru/articles/970304/#comment_29212976</link>
      <description><![CDATA[<p>для облегчения понимания, можно заменить  <code>i + 0</code> на <code>get(i)</code> где <code>func get(i int) int { return i }</code><br>и в обоих случаях и <code>get(i)</code> и<code>i + 0</code> это отдельные операции, которые выполняются до того, как дошло дело до <code>ch &lt;-</code><br>и в обоих этих случаях значение переменной i было вычислено до того как дошло до <code>ch &lt;-</code><br></p>]]></description>
      <pubDate>Fri, 05 Dec 2025 22:22:43 GMT</pubDate>
      <dc:creator><![CDATA[]]></dc:creator>
    </item>
  

  
    <item>
      <title>05.12.2025 21:26:21 </title>
      <guid isPermaLink="true">https://habr.com/ru/articles/970304/#comment_29212816</guid>
      <link>https://habr.com/ru/articles/970304/#comment_29212816</link>
      <description><![CDATA[<p>Так нет же, одинаково оно вычисляется<br>просто при ch &lt;- i + 0 здесь не одна операция отправки в канал, а две операции: ch &lt;- и i + 0, и первая из них это сложение i + 0 и она вычисляется первой потому что исполнение в этом сулчае справа налево, до того как перейти к следующей, и для вычисления этой операции необходимо получить значение i и сложить с 0 и получившееся значение передать в следующую операцию, поэтому когда дело доходит до ch &lt;- то здесь уже не ch &lt;- i а ch &lt;- (значение получившееся от предыдущей операции сложения)<br>в случае когда у нас нет сложения, то у нас одна операция<br><br>все согласно спецификации языка, нет никаких странностей</p>]]></description>
      <pubDate>Fri, 05 Dec 2025 21:26:21 GMT</pubDate>
      <dc:creator><![CDATA[]]></dc:creator>
    </item>
  

  
    <item>
      <title>29.11.2025 09:14:16 </title>
      <guid isPermaLink="true">https://habr.com/ru/articles/970304/#comment_29180850</guid>
      <link>https://habr.com/ru/articles/970304/#comment_29180850</link>
      <description><![CDATA[<p>А в чем странность поведения?</p><p>Отправка в канал происходит не в момент инструкции &lt;- а в момент когда есть либо читатель либо буфер. </p><p>При прибавлении 0 к переменной тоже вполне себе все стандартно, так как тут две операции, первая это сложение и вторая отправка в канал, сначала выполняется сложение, а потом блокируется горутина в ожидании когда у канала появится читатель для того чтобы передать значение.</p>]]></description>
      <pubDate>Sat, 29 Nov 2025 09:14:16 GMT</pubDate>
      <dc:creator><![CDATA[]]></dc:creator>
    </item>
  

  
    <item>
      <title>15.08.2017 05:50:28 </title>
      <guid isPermaLink="true">https://habr.com/ru/companies/wirex/articles/405511/#comment_18298135</guid>
      <link>https://habr.com/ru/companies/wirex/articles/405511/#comment_18298135</link>
      <description><![CDATA[Упс, не обратил внимания, что это перевод, а не ваш текст. В общем по поводу критики текста это не к вам, а к Dr Gideon Greenspan, не уверен правда, что он сюда заглядвает :)]]></description>
      <pubDate>Tue, 15 Aug 2017 05:50:28 GMT</pubDate>
      <dc:creator><![CDATA[]]></dc:creator>
    </item>
  

  
    <item>
      <title>15.08.2017 05:41:33 </title>
      <guid isPermaLink="true">https://habr.com/ru/companies/wirex/articles/405511/#comment_18298133</guid>
      <link>https://habr.com/ru/companies/wirex/articles/405511/#comment_18298133</link>
      <description><![CDATA[Как-то вы не расскрыли свой посыл, как мне кажется.<br>
<br>
Взаимодействие с внешними сервисами у вас в тексте так и не расскрыто почему это невозможно?<br>
<br>
То есть мы имеем блокчейн, который по сути представляет из себя распеределенный реестр с консенсусом. Есть понятие смартконтракта позволяющего осуществлять транзакции в этом реестре.<br>
<br>
То есть некто X выпускает смартконтракт, который в зависимости от наступления условия Y зачислит условно на ваш баланс Z% от некоторой суммы. Проверку наступления условий смартконтракт осуществляет обращаясь к оракулу, можно даже не одному, а нескольким, разным, и условие считается наступившим, только в случае если все оракулы ответили одинаково. <br>
<br>
Есть ли в этом сценарии потеря децентрализаиции и появляются ли некоторые доверенные участники? Да. Но сам реестр продолжает быть таким каким он был, без потери своих свойств. То есть у нас просто есть смартконтракт, который по сути является программным кодом и представляет из себя аналог обычного бумажного контракта, только за его исполнением следит программный код. В этом и есть основная суть смартконтрактов. А вы как потребитель выбираете чей смартконтракт вам интересен и на чьи условия вы готовы согласиться.<br>
<br>
В одном случае у вас есть некий централиованный участник, которому все верят, пусть это будет страховая компания и всякий раз вам придется бадаться именно с этим участником и его трактковками, то есть мы имеем того самого посредника, от которых нам предлагает избавиться вся эта движуха вокруг блокчейн технологий. Заменить центрального участника крайне сложно. <br>
<br>
С другой стороны мы имеем программный код работу которого может проверить любой участник системы, то есть мы избавляемся от центрального посредника. Есть оракулы, в случае недобросовестного поведения которых их заменить на порядки проще нежели центрального посредника и при этом сама система не утратит своей работоспособности.<br>
<br>
Оракулы имеют свою комиссию и поэтому предоставление некорректных данных поставит крест на его существовании, так как факт предоставления таких данных будет отражен в том самом распределенном реестре.<br>
<br>
То есть в итоге смартконтракты служат для уменьшения посредников и повышения прозрачности.<br>
<br>
Ну и раз уж я тут засветился, то хочу высказаться по поводу Wirex так как являюсь пожалуй одним из первых его пользователей. Это ведь ваш сервис, не так ли?<br>
Ребята реализация на крайне низком уровне, и ладно бы черт с ним с глюками, но ваш подход зажать деньги пользователя объясняя это какими-то странными попытками системы застраховаться от скачков стоимости транзакции и при этом зажимаемая вами сумма является фактически не выводимой это уже очень странно. В моем понимании это эквивалентно краже средств пользователя, хотя конечно де-юре кражей не является. И понятно, что сумма крайне незначительная для отдельно взятого пользователя, но если с каждого по чуть-чуть то общая сумма выходит очень даже внушительной. <br>
И вот мое мнение, что вся эта движуха с блокчейн технологиями вообще и смартконтрактами в частности как раз и стремится к избавлению от таких недобросовестных посредников как вы. <br>
<br>
Все это мое оценочное суждение :)]]></description>
      <pubDate>Tue, 15 Aug 2017 05:41:33 GMT</pubDate>
      <dc:creator><![CDATA[]]></dc:creator>
    </item>
  

  
    <item>
      <title>12.08.2016 06:07:14 </title>
      <guid isPermaLink="true">https://habr.com/ru/articles/305272/#comment_9747882</guid>
      <link>https://habr.com/ru/articles/305272/#comment_9747882</link>
      <description><![CDATA[На счет запросов снаружи не совсем понял суть проблемы. Если имеется в виду как организовано общение с браузером клиента, то это примерно так: есть приложение SPA на Reactjs, которое общается с нашим API, которое доступно снаружи, API в свою очередь посылает события в диспетчер и точно также получает события из диспетчера по результатам, которых меняет свое состояние. Сейчас идем к тому, что API будет получая определенные события, отправлять сообщения на клиент посредством SSE.<br/>
<br/>
В качестве песочницу у нас stage сервер, который максимально приближен по состоянию к проду, там можно погонять свои сервисы посмотреть как они себя поведут в реальной жизни.<br/>
<br/>
Дефолтного ТЗ нет, мы стараемся не пользоваться шаблонами в таких вопросах как постановка задач, каждый раз это написание с нуля и продумывание деталей, зато с каждым разом мы открываем все новые и новые детали =)]]></description>
      <pubDate>Fri, 12 Aug 2016 06:07:14 GMT</pubDate>
      <dc:creator><![CDATA[]]></dc:creator>
    </item>
  

  
    <item>
      <title>10.08.2016 15:10:47 </title>
      <guid isPermaLink="true">https://habr.com/ru/articles/305272/#comment_9745426</guid>
      <link>https://habr.com/ru/articles/305272/#comment_9745426</link>
      <description><![CDATA[Диспетчер от сервиса должен дождаться только подтверждения, что сообщение получено, задерживать диспетчер не хорошо, у него работы много =)<br/>
Да, есть блокирующиеся вызовы, это обращения напрямую от сервиса к сервису, такие у нас тоже есть, но их очень мало, как правило это получение каких-то данных, которые есть в другом сервисе. Мы иногда думаем над тем, чтобы заменить и такие вызовы, чем то вроде:<br/>
сервис А кидает сообщение в диспетчер что ему нужны данные Y (событие: «нужны данные Y»)<br/>
диспетчер посылает уведомление в сервисы/сервис которые обладают этими данными, на самом деле диспетчер не знает, кто обладает этими данными, диспетчер просто знает, что сервис B попросил уведомлять его о событиях «нужны данные Y» <br/>
сервис или сервисы B получив такое уведомление, формируют данные и в событии отправляют их в диспетчер, кто быстрее тот и молодец, диспетчер перенаправляет событие с данными в запросивший сервис А. Это позволит избежать ожиданий, когда один сервис висит ожидая данных от другого, к тому же есть возможность получить данные от того сервиса кто сделает это быстрее. Но пока мы в случае когда необходимо просто получить данные другого сервиса у нас выполняется прямой запрос из одного сервиса в другой, таких вызовов очень немного и м не хотим чтобы их кол-во росло, потому что сложнее за всем этим потом следить.]]></description>
      <pubDate>Wed, 10 Aug 2016 15:10:47 GMT</pubDate>
      <dc:creator><![CDATA[]]></dc:creator>
    </item>
  

  
    <item>
      <title>10.08.2016 14:46:07 </title>
      <guid isPermaLink="true">https://habr.com/ru/articles/305272/#comment_9745372</guid>
      <link>https://habr.com/ru/articles/305272/#comment_9745372</link>
      <description><![CDATA[<a href="https://habrahabr.ru/users/claygod/" class="user_link">claygod</a> извиняюсь за задержку.<br/>
в одном комментарии пожалуй все сразу не расскажешь. У нас есть некоторые требовавния к микросервисам, они должны предоставлять HTTP API, они должны слать метрики и должны слать логи. Эти требования обязательные. Все остальное в общем достаточно гибко, каждый микросервис может быть реализован на каком-то своем технологическом стеке, в том числе и каждый сервис сам решает нужна ли ему внутри очередь или нет. В какой то мере диспетчер выполняет роль очереди на уровне приложения, тем не менее каждый микросервис может использовать свои очереди, есть доступные инструменты, которые уже настроены и работают и которыми может воспользоваться любой сервис, например RabbitMQ.<br/>
Микросервисы у нас по своей природе асинхронные, более того все общение происходит через диспетчер, куда каждый микросервис посылает событие при изменившемся состоянии, на это событие могут реагировать другие сервисы в результате чего также изменят свое состояние и кинут свое событие в диспетчер.<br/>
на счет REST не могу сказать, что мы во всех микросервисах остались в рамках идеально чистого REST, но в целом это работает, что касается асинхронных задач, то в целом наш подход похож на описываемый здесь http://restcookbook.com/Resources/asynchroneous-operations/<br/>
вебсокеты не применяли, пока. В ближайшее время выкатим решение на SSE]]></description>
      <pubDate>Wed, 10 Aug 2016 14:46:07 GMT</pubDate>
      <dc:creator><![CDATA[]]></dc:creator>
    </item>
  

  
    <item>
      <title>11.07.2016 08:41:42 </title>
      <guid isPermaLink="true">https://habr.com/ru/articles/305272/#comment_9694808</guid>
      <link>https://habr.com/ru/articles/305272/#comment_9694808</link>
      <description><![CDATA[Да, в некоторых случаях контейнеры слушают внешние интерфейсы железки и да это неудобно, согласен. <br/>
Когда начинали небыло столь широкого выбора инструментов готовых для запуска в проде, поэтому сделали так. Сейчас собираемся менять схему, пока не решили, что имено будем использовать, смотрим в сторону docker swarm и kubernets, так что этот выбор нам еще предстоит сделать. Ну а когда решим готовы поделиться опытом, ну и чужой опыт всегда ценим, лучше учиться на чужих ошибках, чем на своих]]></description>
      <pubDate>Mon, 11 Jul 2016 08:41:42 GMT</pubDate>
      <dc:creator><![CDATA[]]></dc:creator>
    </item>
  

  
    <item>
      <title>11.07.2016 07:11:39 </title>
      <guid isPermaLink="true">https://habr.com/ru/articles/305272/#comment_9694612</guid>
      <link>https://habr.com/ru/articles/305272/#comment_9694612</link>
      <description><![CDATA[1. нет nginx не на каждом хосте, то есть возможны например варианты поднимаем инстанс на амазоне, запускаем в нем один контейнер, добавляем запись в апстрим, то есть по сути nginx может быть вообще один, который проксирует запросы контейнерам в том числе и на разных машинах, но на деле получается nginx не один. Админим не руками, ansible'ом, пока мы небольшие справляемся.<br/>
2. И тут ansible и опять же пока мы небольшие этого достаточно, но в целом экспериментируем и ищем пути большей автоматизации с целью большего исключения человеческого фактора. Переключаем тоже используя ansible, в идеале конечно настроить автоматическое переключение и откат в случае неудачи. То есть например при запуске нового контейнера (green) автоматом часть трафика заруливается на него, в течении какого то времени собираются метрики и если заданные пороговые значения не превышены, то старый контейнер (blue) выключается, а весь трафик заруливается на green, если же пороговые значения превышены, то весь трафик возвращается на blue. Но пока делаем это руками используя ansible<br/>
3. Мониторинг, тут есть какбы две стороны медали, первая сервис сам о себе шлет некоторый набор метрик — это первая сторона и вторая — это действительно нужен отдельный процесс, но не нужен в том же контейнере, у нас запущен в отдельном контейнере c -v /var/run/docker.sock:/var/run/docker.sock --pid=host чего в большинстве случаев достаточно для мониторинга, по крайней мере нам пока хватает. <br/>
А вот на счет идеологии докера, к сожалению мы иногда ее нарушаем, хотя стараемся этого не делать. Приведу пример плохой практики случавшейся у нас: — микросервис на php, который также требует запуска некоторой команды по расписанию, выполнено в виде контейнера с php-fpm и кроном. Сейчас наученные опытом мы избегаем таких решений, но тем не менее это случалось в нашей практике и до сих пор остались микросервисы работающие в таком исполнении.<br/>
4. и да и нет, сервисы свои логи пишут в логстеш, есть еще datadog, который имеет готовые решения для логирования некоторых событий докера]]></description>
      <pubDate>Mon, 11 Jul 2016 07:11:39 GMT</pubDate>
      <dc:creator><![CDATA[]]></dc:creator>
    </item>
  

  
    <item>
      <title>09.07.2016 11:49:24 </title>
      <guid isPermaLink="true">https://habr.com/ru/articles/305272/#comment_9693434</guid>
      <link>https://habr.com/ru/articles/305272/#comment_9693434</link>
      <description><![CDATA[Ну на самом деле почти каждый из этих вопросов тянет на отдельную статью. Но если коротко, то:<br/>
<br/>
1. docker-контейнеры на нескольких серверах — это вообще отдельная большая история в том числе и для нас, есть куда развиваться и что еще попробовать, но в общих чертах все запросы проходят через reverse proxy то есть поднимая еще одну копию сервиса в докер контейнере мы просто дописываем нужную запись в upstream у nginx, при этом физически два контейнера могут быть запущены на разных машинах<br/>
<br/>
2. запускаем ли одинаковые микросервисы на одном хосте? Да, как минимум при деплое, я упоминал, что мы используем BGD технику, которая подразумевает в какой то момент работу параллельно двух контейнеров одного микросервиса.<br/>
<br/>
3. Для мониторинга у нас используется DataDog, influxdb + grafana, но мы продолжаем экспериментировать в этом направлении, потому как мониторинг при нашем подходе очень важная составляющая, собираемся попробовать prometheus<br/>
<br/>
4. Логируем logstash + Elastic но тоже продолжаем экспериментировать в этом направлении, эта связка не очень нравится своей громоздкостью, но пока не нашли достаточно надежной, обкатанной альтернативы]]></description>
      <pubDate>Sat, 09 Jul 2016 11:49:24 GMT</pubDate>
      <dc:creator><![CDATA[]]></dc:creator>
    </item>
  

  
    <item>
      <title>08.07.2016 11:56:16 </title>
      <guid isPermaLink="true">https://habr.com/ru/articles/305272/#comment_9692414</guid>
      <link>https://habr.com/ru/articles/305272/#comment_9692414</link>
      <description><![CDATA[Диспетчер построен на базе RabbitMQ плюс некоторые свои обвязки позволяющие либо объединять некоторые потоки событий, либо наоборот дробить в зависимости от нагружености и потребностей. События диспетчер рассылает используя push подход, то есть сервису не нужно держать коннект с диспетчером.]]></description>
      <pubDate>Fri, 08 Jul 2016 11:56:16 GMT</pubDate>
      <dc:creator><![CDATA[]]></dc:creator>
    </item>
  

  
    <item>
      <title>01.11.2013 13:56:36 </title>
      <guid isPermaLink="true">https://habr.com/ru/companies/JetBrains/articles/198510/#comment_6933214</guid>
      <link>https://habr.com/ru/companies/JetBrains/articles/198510/#comment_6933214</link>
      <description><![CDATA[Да, это бесспорно очень полезная фича, если работает как надо, думаю в шторме она хорошо работает. Но не знаю как у других, на моей практике выходит так, что во-первых «на 10 уровней» это как бы повод задуматься над кодом, в других случаях (где отсутствует 10-ти уровневая иерархия наследования) более простых инструментов навигации по коду вполне хватает, с подсказками при написании кода тоже самое, кто-то использует их и в виме, я не использую совсем, отвлекают. <br/>
Вполне могу допустить, что IDE будет выигрывать если меняешь проекты часто, скажем каждые пару месяцев.<br/>
В случае долго-живущих крупных проектов, в моем случае, выходит так что на первое место выходят другие фичи, которые необходимы, удобство и быстрота написания кода, гибкость в настройке под себя, взаимодействие с внешним миром (в виде различных сторонних утилит, сервисов и прочего) которые так же можно быстро настроить под себя или реализовать. <br/>
И да, мой случай это не только я :) но все те люди с которыми я либо работаю вместе, либо общаюсь весьма часто.<br/>
<br/>
Ну в общем на вкус и цвет все фломастеры разные, думаю многое еще зависит от специфики работы вообще и проекта/ов в частности.]]></description>
      <pubDate>Fri, 01 Nov 2013 13:56:36 GMT</pubDate>
      <dc:creator><![CDATA[]]></dc:creator>
    </item>
  

  
    <item>
      <title>31.10.2013 15:31:31 </title>
      <guid isPermaLink="true">https://habr.com/ru/companies/JetBrains/articles/198510/#comment_6929680</guid>
      <link>https://habr.com/ru/companies/JetBrains/articles/198510/#comment_6929680</link>
      <description><![CDATA[разные варианты анализаторов кода есть<br/>
автодополнение методов класса вряд ли, точно сказать не могу, не люблю подсказки во время написания кода (вообще никакие), так как пишу я быстро, большинство реализаций в виде выпадающих плашек отвлекают, а вот более полезные (на мой взгляд) снипеты есть думаю даже у самых примитивных текстовых редакторов.<br/>
<br/>
опять же повторюсь IDE выиграет, когда программисту нужна помощь при написании кода, а когда такая навязчивая помощь чаще мешает, чем помогает, то хочется как можно меньше вторжений извне во время изложения идеи в коде.]]></description>
      <pubDate>Thu, 31 Oct 2013 15:31:31 GMT</pubDate>
      <dc:creator><![CDATA[]]></dc:creator>
    </item>
  

  
    <item>
      <title>31.10.2013 11:56:46 </title>
      <guid isPermaLink="true">https://habr.com/ru/companies/JetBrains/articles/198510/#comment_6928664</guid>
      <link>https://habr.com/ru/companies/JetBrains/articles/198510/#comment_6928664</link>
      <description><![CDATA[За Sublime не скажу, потому как мы используем vim, сказал об этом выше, так вот vim позволяет настроить всё под свои привычки и максимально повысить продуктивность. Все кто у нас сейчас работают с vim и все кто у нас сейчас не работают, но продолжают использовать vim в других компаниях пришли к нему через использование тех или иных IDE, никто не вернулся обратно.<br/>
<br/>
Сравнивать текстовый редактор с IDE как продукт, вообще не имеет смысла, а вот в рамках удобного использования и повышения продуктивности очень даже можно. В руках новичка, либо средней руки программиста IDE выиграет, а вот в руках опытного профессионального разработчика не факт. В случае с моим отделом IDE проигрывает в 100% случаев.]]></description>
      <pubDate>Thu, 31 Oct 2013 11:56:46 GMT</pubDate>
      <dc:creator><![CDATA[]]></dc:creator>
    </item>
  

  
    <item>
      <title>30.10.2013 08:19:13 </title>
      <guid isPermaLink="true">https://habr.com/ru/companies/JetBrains/articles/198510/#comment_6923782</guid>
      <link>https://habr.com/ru/companies/JetBrains/articles/198510/#comment_6923782</link>
      <description><![CDATA[да, но зачастую в руках профессионала SublimeText выигрывает у PhpStorm.<br/>
у нас в отделе все работают в vim, не потому что он бесплатен, а потому что так уж сложилось, что он прижился проще и лучше остальных.]]></description>
      <pubDate>Wed, 30 Oct 2013 08:19:13 GMT</pubDate>
      <dc:creator><![CDATA[]]></dc:creator>
    </item>
  

  
    <item>
      <title>30.10.2013 08:16:28 </title>
      <guid isPermaLink="true">https://habr.com/ru/companies/JetBrains/articles/198510/#comment_6923768</guid>
      <link>https://habr.com/ru/companies/JetBrains/articles/198510/#comment_6923768</link>
      <description><![CDATA[вы видимо никогда не работали строителем :)]]></description>
      <pubDate>Wed, 30 Oct 2013 08:16:28 GMT</pubDate>
      <dc:creator><![CDATA[]]></dc:creator>
    </item>
  

      

      

    
  </channel>
</rss>
