Xping - утилита контроля качества связи
С тех пор, как выборы у нас стали считаться формой экстремизма - качество интернет-связи в Москве упало невероятно. Для примера возьмем лучший московский датацентр Hoster.ru (это сказано без иронии - я действительно так думаю, о худших я скажу дальше). Давайте взглянем на трассировку канала к некому серверу, находящемуся на нем. Результаты впечатляют. Сначала на 38 мс подвисла крупная магистраль по Москве gldn.net на допотопном кабеле категории 04, потом на 56 мс подвис шлюз на входе в эту же магистраль, потом аж на 184 мс подвис шлюз на выходе этой магистрали на Hoster.ru и одновременно вовремя шлюз внутри Hoster.ru не принял ответа от целевого сервера. Дальше больше - по самому Hoster.ru пакет cтал проходить к целевому серверу через откуда-то взявшийся сначала девятый шлюз, а потом и через десятый.
Что же говорить о худших датацентрах? Вот трасса к небольшому хостингу itsoft.ru, находящемуся в районе Фили. Скорость прохождения пакета здесь стабильна - вот только ходят пакеты туда из центра Москвы дольше, чем до Лондона.
Многие подмосковные хостинги, такие как Agava.ru - расположены как будто бы на другой планете. Например пакет по той же самой допотопной магистрали категории 4 прошел в направлении к Агаве за 310 мс, затем подвис на 48 мс на той же крупной магистрали gldn.net. Затем пакет вышел на междугороднюю связь Москва-Долгопрудный, который прошел аж за 121 мс. И затем три шлюза по Долгопрудному по 21 мс. Для сравнения, я взял город за 1000 километров от Москвы. Как видите, там всего два шлюза по 35 и один шлюз видимо в самом датацентре Белгорода.
То есть до Белгорода - около 100 мс, а до Долгопрудного - 600 мс. По-моему как раз за такое время сигнал доходит до Луны и обратно.
Но это лишь одна грань вопроса - собственно качество каналов связи у нас в Москве. Есть и другая грань - откровенный беспредел интернет-провайдеров в отношении частных потребителей. Вызван он ровно теми же причинами, что и качество каналов связи - всеобщим бардаком и коррупцией (крышеванием "правоохранителями" крупных игроков телекоммуникационного рынка). И, соответственно, пониманием крупными игроками абсолютной своей безнаказанности по отношении к гражданам, конечным потребителям их услуг.
Опять же, наверное, нет смысла говорить о худших - поговорим о лучших, например о самом быстром в Москве провайдере Corbina Telecom. Вот до какого состояния надо довести человека, чтобы он написал вот такое письмо? Учитывая что все-таки к дому подходит всего-то два провайдера.
В течении месяца как минимум я не смог добиться, чтобы оплаченный мною внешний айпишник был достижим и видим из интернета.
При этом я почти каждый день звонил и уговаривал их. Предлагал сам подъехать к ним и настроить им шлюз. Бесполезно.
Любопытно выглядит даже переписка с Corbina telecom. Например я создаю заявку на Support. В ней первой же фразой указываю, что прошивка именно та, которая рекомендована корбиной и сгружена именно с сайта Корбины. Ответ приходит интересный - с рекомендацией прошить фаервол тем, чем он и был прошит. А надо сказать, что со стандартной прошивкой роутеров корбина почему-то работать не умеет. Подключение возможно лишь через несколько весьма специфичных и странных устройств, которые рекомендованы на этой страничке. Непонятно, если я ко всем коннекчусь с помощью ZyWall 70 - и привык с ним работать - почему нельзя поднять на VPN-сервере обычный стандартный PPPOE или обычный стандартный PPPTP? Ведь это же крупная фирма - Билайн. Неужели нет денег на стандартный VPN-сервер? Но мне хотелось подключиться к этому быстрому провайдеру и я приобрел сначала одно это странное малопроизводительное устройство, а потом и второе. Естественно, без особой нестандартной прошивки к странному корбиновскому VPN они не коннектятся. Естественно, если я вообще получаю хоть что-то, и коннект падает - значит устройства уже перепрошиты. В противном случае - ничего внутри тоннеля получить в принципе невозможно. Собственно об этом - первая фраза моей заявки на суппорт. В ответ на эту заявку получаю чудо-ответ с предложением перепрошить свой роутер прошивкой с сайта. Я в ответе я пишу суппорту, что ведь роутер/фаервол как раз этой прошивкой и прошит - в этом и суть заявки на суппорт. Немного напоминает разговор глухого со слепым, не правда ли? После этого замечания разговор красиво заходит в тупик. Мое замечание с первоначальной заявкой перекодируется и возвращается вместе с ответом в виде абракадабры. На это уже ничего ответить невозможно в принципе - ну как бы Yahoo отработало неверно и я сам виноват, что не прочитал умного совета корбиновского чудо-суппорта. Дальше делай что хочешь - деньги ты заплатил, суппорт вроде-бы обработал заявку о проблеме и ответил, а стабильного интернет-канала как не было - так и нет.
А ведь Корбина - это лучший интернет-провайдер. У него хотя бы прямой канал (от интернета к клиенту) рвался, но был. А по поводу худших интернет-провайдеров (которые не то что со внешним айпишником, но вообще выход в интернет наладить не могли) я даже написал жалобу в федеральную инспекцию электросвязи. Приложил неопровержимые доказательства, что интернет у них на канале был всего два-три для в неделю (!). И за период двух месяцев ни разу не было интернета более 4 дней в неделю.
Ответ пришел из Правительства Москвы. В ответе было указано, что эти линии связи правительству Москвы не принадлежат и лицензию у Акадо отозвать невозможно. Мое заявление перепроверялось 17.06.2008 и 18.06.2008. Какие-то проверяющие мое заявление барышни многократно перезванивали и им и мне в эти дни. Все равно Акадо не удалось поднять интернет в Жулебино хотя бы на момент проверки. Ну никак не удалось! Правда получать деньги от абонентов в Жулебино им эта мелочь не помешала.
Ах, бедное Акадо! Могу себе представить как бульдозер ездит взад-вперед по их кабелям, а доблестные работники Акадо с лопатами и паяльниками только и делают что починяют и починяют свои кабели. И занимаются этим нужным и благородным делом непрерывно - 3-4 дня каждую неделю! А проклятые бульдозеры рвут и рвут их кабели - даже в те дни, когда их деятельность проверяет Комиссия московского правительства!
Думаю, историю о качестве связи в Москве можно было бы продолжать бесконечно. Согласитесь, было бы удивительно, если бы взрывалась Саяно-Шушенская ГРЭС, тонули бы подводные лодки Курск, горели бы Останкинские телебашни, Евсюковы бы расстреливали людей в универсамах, ежедневно сотни тысяч человек бы стояли в Москве пробке (а в метро уже 140 человек с начала года просто задавили в давке), киллеров-отравителей, слегка отряхнувших с рук Полоний-210, принимали бы работать депутатами Государственной думы, взрывались бы жилые дома, а подрывателей бы ловили в Рязани и отпускали с миром, TV ежедневно крутило ролики бы о возрождении и величии нации в стиле Муссолини (позабыв как ответил Муссолини за свои речи "Вперед Италия" и "Италия поднимается с колен"), детей в Беслане срочно бы расстреливали из танков - потому что Масхадов обещал приехать и убрать террористов из школы, руководители ведомства борьбы с наркотиками скончались бы в сауне (находившейся прямо в их рабочем офисе) от передозировки, ежедневно люди продолжали бы погибать на маленькой победоносной войне на Кавказе, закрылся бы Москвич и АвтоВаз, а НКВД-ФСБ перешло на ношение черной гестаповской формы, кремлевские карлики активизировались бы и под шумок безнаказанно отнимали бы миллиарды долларов у Ходорковского и телеканалы у Гусинского, сынок какого-нибудь сосковца мог бы насмерть задавить четырех человек и получить только выговор от отца за помятый бампер, московскй мэр понимал бы поддержку предпринимательства как выделение собственной жене 1300 гектаров земли под застройку в Москве, суды бы давали сроки за убийство (офицера-подводника Пуманэ) в размере четырех месяцев условно, обрушивались бы аквапарки, самолеты и вертолеты, травили бы газом заложников Норд-Оста, в разрар кризиса разгоняли бы крупнейшие в стране мелкооптовые рынки, избирательные комиссии заявляли бы что в поддержку Едра проголосовало 114 процентов от проживающих в Дагестане, а 106 процентов подписей, поданных за Солидарность являются фальшивыми и так далее и так далее и так далее, но... - но во всей этой фантасмагории интернет-линии связи прекрасно бы работали! И провайдеры интернет-услуг наперегонки спешили удовлетворить потребителей своих услуг. Согласитесь - это нереально.
В интернете все обстоит ровно так же, как и везде. Сигнал от Москвы до Белгорода доходит за 100 мс, до Филей за 180 мс, а до Долгопрудного за 600 мс. Дойдя же наконец до нужного Датацентра, сигнал вообще забывает куда он пришел и начинает бродить в нем кругами 500-700-1800 мс, пока не вспомнит к какому серверу он пришел.
А почему нет? Почему электронный импульс должен вести себя во всей этой окружающей фантасмагории иначе? Ведь у нас даже молнии спокойно проходят двойную-тройную молниезащиту и спокойно поджигают нефтеперкачиващие станции - причем они сделали это минимум дважды за последний месяц (22 августа в Конге или 26 августа в БузулукНефти).
Сделать со всем этим безобразием, конечно же, нельзя ничего. Но можно хотя бы зафиксировать его. И для себя лично попытаться подобрать что-то лучшее из худшего.
Именно для этой цели существует моя утилитка Xping, которая в отличие от стандартной умеет запоминать все в базу. Запоминается все довольно экономно - одного винчестера хватит на много лет. К тому же вы в любой момент можете ее переделать для своих нужд, тк ее исходный код перед вами:
1: Module Module1
2:
3: Sub Main(ByVal args() As String)
4: Dim TimeountInterval As Integer = 1000 '1 sec
5: Dim SleepTime As Integer = 10000 '10 sec
6: Dim IpAddr As String '= "89.188.102.246" or "SQL.RU"
7: Dim ToSql As Boolean = False
8: Dim CN As Data.SqlClient.SqlConnection
9: Dim CMD As SqlClient.SqlCommand
10: Try
11: If args.Length = 0 Then
12: help1:
13: Console.WriteLine("Usage: IpAddress SleepTimeSecond TimeountSecond")
14: Console.WriteLine("Usage: 82.199.96.143 10 1")
15: Console.WriteLine("or")
16: Console.WriteLine("Usage: SQL.RU SleepTimeSecond TimeountSecond")
17: Console.WriteLine("Ответ 82.199.96.143 ждем секунду, повторяем каждые 10 секунд")
18: Console.WriteLine("SleepTimeSecond, TimeountSecond можно опустить")
19: Console.WriteLine("В ответе: TTL - Time to Live, RTT - Round Trip time")
20: Console.WriteLine("or")
21: Console.WriteLine("Usage: SQL.RU SleepTimeSecond TimeountSecond /ToSQL")
22: Console.WriteLine("Ответ пишется в базу, SqlConnectionString задан в Xping.config")
23: Console.WriteLine("CREATE TABLE [dbo].[Xping](")
24: Console.WriteLine(" [i] [int] IDENTITY(1,1) NOT NULL,")
25: Console.WriteLine(" [IP] [nvarchar](50) NULL,")
26: Console.WriteLine(" [Status] [int] NULL,")
27: Console.WriteLine(" [Time] [datetime] NULL,")
28: Console.WriteLine(" [TTL] [int] NULL,")
29: Console.WriteLine(" [RTT] [int] NULL,")
30: Console.WriteLine(" [Message] [nvarchar](max) NULL,")
31: Console.WriteLine(" CONSTRAINT [PK_Ping] PRIMARY KEY CLUSTERED ")
32: Console.WriteLine("(")
33: Console.WriteLine(" [i] ASC")
34: Console.WriteLine(")WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]")
35: Console.WriteLine(") ON [PRIMARY]")
36: Console.WriteLine("GO")
37: Console.ReadLine()
38: Exit Sub
39: ElseIf args.Length = 1 Then
40: IpAddr = GetIpAddr(args(0))
41: ElseIf args.Length = 2 Then
42: IpAddr = GetIpAddr(args(0))
43: SleepTime = CInt(args(1)) * 1000
44: ElseIf args.Length = 3 Then
45: IpAddr = GetIpAddr(args(0))
46: SleepTime = CInt(args(1)) * 1000
47: TimeountInterval = CInt(args(2)) * 1000
48: ElseIf args.Length = 4 Then
49: IpAddr = GetIpAddr(args(0))
50: SleepTime = CInt(args(1)) * 1000
51: TimeountInterval = CInt(args(2)) * 1000
52: ToSql = True
53: Else
54: GoTo Help1
55: End If
56: '
57: Console.WriteLine(IpAddr & " (TTL - Time to Live, RTT - Round Trip time)")
58: Console.WriteLine()
59: '
60: If ToSql Then
61: CN = New Data.SqlClient.SqlConnection(My.Settings.SqlConnectionString)
62: Try
63: CN.Open()
64: Catch ex As Exception
65: Console.WriteLine(ex.Message)
66: End Try
67: Try
68: CMD = New SqlClient.SqlCommand(My.Settings.WriteCMD, CN)
69: CMD.Parameters.AddWithValue("@IP", IpAddr)
70: CMD.Parameters.Add("@Status", SqlDbType.Int)
71: CMD.Parameters.Add("@TTL", SqlDbType.Int)
72: CMD.Parameters.Add("@RTT", SqlDbType.Int)
73: CMD.Parameters.Add("@Message", SqlDbType.NVarChar)
74: Catch ex As Exception
75: Console.WriteLine(ex.Message)
76: End Try
77: End If
78: '
79: Dim Xping As New System.Net.NetworkInformation.Ping
80: Dim ANSI As New System.Text.ASCIIEncoding
81: '
82: While True
83: Dim Replay As System.Net.NetworkInformation.PingReply = Xping.Send(IpAddr, TimeountInterval)
84: If Replay.Status = Net.NetworkInformation.IPStatus.Success Then
85: Console.WriteLine("TTL=" & Replay.Options.Ttl & ", " & "RTT=" & Replay.RoundtripTime & ", Time=" & Now.ToString) '& ", ReplayBuff=" & ANSI.GetString(Replay.Buffer))
86: If ToSql Then
87: CMD.Parameters("@Status").Value = 0
88: CMD.Parameters("@TTL").Value = Replay.Options.Ttl
89: CMD.Parameters("@RTT").Value = Replay.RoundtripTime
90: CMD.Parameters("@Message").Value = "OK"
91: CMD.ExecuteNonQuery()
92: End If
93: Else
94: Console.WriteLine("Status=" & Replay.Status.ToString)
95: If ToSql Then
96: CMD.Parameters("@Status").Value = Replay.Status
97: CMD.Parameters("@TTL").Value = -1
98: CMD.Parameters("@RTT").Value = -1
99: CMD.Parameters("@Message").Value = Replay.Status.ToString
100: CMD.ExecuteNonQuery()
101: End If
102: End If
103: System.Threading.Thread.Sleep(SleepTime)
104: End While
105: Catch ex As Exception
106: Console.WriteLine(ex.Message)
107: Console.ReadLine()
108: End Try
109:
110:
111: End Sub
112:
113: Function GetIpAddr(ByVal Str1 As String) As String
114: If Str1 <> "" Then
115: 'определим это адрес или имя сначала
116: Dim Tst1() As String
117: Tst1 = Str1.Split(".")
118: If Tst1.Length = 4 Then
119: If IsNumeric(Tst1(0)) And IsNumeric(Tst1(1)) And IsNumeric(Tst1(2)) And IsNumeric(Tst1(3)) Then
120: Return Str1
121: Else
122: GoTo DNS
123: End If
124: Else
125: DNS: Dim IP_String As New Text.StringBuilder
126: Dim DNS As System.Net.IPHostEntry
127: DNS = System.Net.Dns.GetHostEntry(Str1)
128: For Each One As System.Net.IPAddress In DNS.AddressList
129: Dim IP_Bytes As Byte()
130: IP_Bytes = One.GetAddressBytes()
131: For i As Integer = 0 To IP_Bytes.Length - 1
132: IP_String.Append(String.Format("{0:D2}.", IP_Bytes(i)))
133: Next
134: IP_String.Length -= 1
135: 'возвращается только первый IP адрес - наверное для кластера их может быть несколько
136: Return (IP_String.ToString)
137: Next
138: End If
139: Else
140: Throw New Exception("Address not set")
141: End If
142: End Function
143:
144: End Module
Код прошу строго не судить - написан он на одном дыхании ровно за час. Но дело свое делает:
У проги есть стандартный NET-овский конфиг, в котором надо пределелить коннект к базе и там же лежит комманда записи в базу:
1: <?xml version="1.0" encoding="utf-8" ?>
2: <configuration>
3: <configSections>
4: <sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
5: <section name="Xping.My.MySettings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
6: </sectionGroup>
7: </configSections>
8: <connectionStrings>
9: <add name="Xping.My.MySettings.SqlConnectionString" connectionString="Data Source=.;Initial Catalog=Xping;Integrated Security=True" />
10: </connectionStrings>
11: <system.diagnostics>
12: <sources>
13: <!-- This section defines the logging configuration for My.Application.Log -->
14: <source name="DefaultSource" switchName="DefaultSwitch">
15: <listeners>
16: <add name="FileLog"/>
17: <!-- Uncomment the below section to write to the Application Event Log -->
18: <!--<add name="EventLog"/>-->
19: </listeners>
20: </source>
21: </sources>
22: <switches>
23: <add name="DefaultSwitch" value="Information" />
24: </switches>
25: <sharedListeners>
26: <add name="FileLog"
27: type="Microsoft.VisualBasic.Logging.FileLogTraceListener, Microsoft.VisualBasic, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"
28: initializeData="FileLogWriter"/>
29: <!-- Uncomment the below section and replace APPLICATION_NAME with the name of your application to write to the Application Event Log -->
30: <!--<add name="EventLog" type="System.Diagnostics.EventLogTraceListener" initializeData="APPLICATION_NAME"/> -->
31: </sharedListeners>
32: </system.diagnostics>
33: <applicationSettings>
34: <Xping.My.MySettings>
35: <setting name="WriteCMD" serializeAs="String">
36: <value>INSERT [Xping]([IP],[Status],[Time],[TTL],[RTT],[Message])VALUES (@IP, @Status, GETDATE(), @TTL, @RTT, @Message)</value>
37: </setting>
38: </Xping.My.MySettings>
39: </applicationSettings>
40: </configuration>
Ну и конечно, вы должны создать таблу в базе:
1: CREATE TABLE [dbo].[Xping](
2: [i] [int] IDENTITY(1,1) NOT NULL,
3: [IP] [nvarchar](50) NULL,
4: [Status] [int] NULL,
5: [Time] [datetime] NULL,
6: [TTL] [int] NULL,
7: [RTT] [int] NULL,
8: [Message] [nvarchar](max) NULL,
9: CONSTRAINT [PK_Ping] PRIMARY KEY CLUSTERED
10: (
11: [i] ASC
12: )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
13: ) ON [PRIMARY]
14:
15: GO
Вот собственно и все. Xping вы можете сгрузить в бинарном виде. Пишите пожалуйста свои замечания в баг-трекер программы.
|