По вашему запросу ничего не найдено :(
Убедитесь, что запрос написан правильно, или посмотрите другие наши статьи:
img
В программно-конфигурируемой сети (SDN) происходит разделение плоскости передачи и управления данными, позволяющее осуществить программное управление плоскостью передачи, которое может быть физически или логически отделено от аппаратных коммутаторов и маршрутизаторов. Подобный подход дает большое количество плюсов: Возможность видеть топологию всей сети; Возможность конфигурации всей сети в целом, а не отдельных единиц оборудования; Возможность производить независимое обновление оборудования в сети; Возможность контролировать всей сети из высокоуровневого приложения. SDN сети То есть, основное отличие программно-конфигурируемых сетей - делегация задачи вычисления маршрутов контроллеру (плоскость управления) и оставить функцию передачи пакетов (плоскость передачи данных) на отдельных устройствах (коммутаторы OpenFlow) , что снизит нагрузку на маршрутизатор и увеличит его производительность. Для оценки функциональности SDN-сети с элементами NFV можно использовать два основных подхода, со своими достоинствами и недостатками: Метод Достоинства Недостатки Эмуляция Высокая точность, возможность использования настоящего ПО Возможная несовместимость конфигурации с реальным оборудованием Построение сети на реальном оборудовании Высокая точность результатов Высокая стоимость С началом развития в сфере SDN-сетей появилось два эмулятора SDN-сетей, которые в добавок поддерживают симуляцию (возможность тестирования сети, часть оборудования в которой реальна и часть - эмулирована). Рассмотрим эмуляторы подробнее. Mininet Эмулятор, находящийся в свободном доступе, большая часть которого написана на языке Python. Работает с “легковесной” виртуализацией, то есть вся эмулируемая сеть реальна, в том числе и конечные виртуальные машины. Есть возможность подключения любых виртуальных коммутаторов и контроллеров. Достоинства Недостатки Открытый код, бесплатность, быстродействие, поддержка всех контроллеров SDN и протоколов OpenFlow вплоть до 1.3, большое количество обучающих видео Высокая сложность, необходимо знание Python и Linux, отсутствие полноценного графического интерфейса Estinet Эмулятор, все права на который имеет компания Estinet, но для студентов и всех желающих попробовать есть свободный доступ на месяц. Есть удобный графический интерфейс для построения топологии сети, редакции свойств оборудования и запуска эмуляции. Достоинства Недостатки Наглядность, простота настройки и установки, возможность эмуляции LTE и Wi-Fi сетей Закрытость, малое количество обучающих статей и видео, низкая производительность работы, более высокая сложность настройки при использовании не встроенного контроллера Ниже приведена часть программного кода на языке Python для построения сети в эмуляторе Mininet: # Инициализация топологии Topo.__init__( self, **opts ) # Добавление узлов, первые - коммутаторы S1 = self.addSwitch( 's0' ) S2 = self.addSwitch( 's1' ) S3 = self.addSwitch( 's2' ) S4 = self.addSwitch( 's3' ) S5 = self.addSwitch( 's4' ) S6 = self.addSwitch( 's5' ) S7 = self.addSwitch( 's6' ) S8 = self.addSwitch( 's7' ) S9 = self.addSwitch( 's8' ) S10= self.addSwitch( 's9' ) S11= self.addSwitch( 's10') # Далее - рабочие станции(виртуальные машины) H1= self.addHost( 'h0' ) H2 = self.addHost( 'h1' ) H3 = self.addHost( 'h2' ) H4 = self.addHost( 'h3' ) H6 = self.addHost( 'h5' ) H7 = self.addHost( 'h6' ) H8 = self.addHost( 'h7' ) H9 = self.addHost( 'h8' ) H10 = self.addHost( 'h9' ) H11 = self.addHost( 'h10' ) # Добавление каналов связи между коммутатором и рабочей станцией self.addLink( S1 , H1 ) self.addLink( S2 , H2 ) self.addLink( S3 , H3 ) self.addLink( S4 , H4 ) self.addLink( S7 , H7 ) self.addLink( S8 , H8) self.addLink( S9 , H9) self.addLink( S10 , H10) self.addLink( S11 , H11) # Добавление каналов связи между коммутаторами self.addLink( S1 , S2, bw=1, delay='0.806374975652ms') self.addLink( S1 , S3, bw=1, delay='0.605826192092ms') self.addLink( S2 , S11, bw=1000, delay='1.362717203ms') self.addLink( S3 , S10, bw=1000, delay='0.557936322ms') self.addLink( S4 , S5, bw=1000, delay='1.288738ms') self.addLink( S4 , S7, bw=1000, delay='1.1116865ms') self.addLink( S5 , S6, bw=1000, delay='0.590828707ms') self.addLink( S5 , S7, bw=1000, delay='0.9982281ms') self.addLink( S6 , S10, bw=1000, delay='1.203263ms') self.addLink( S7 , S8, bw=1000, delay='0.2233403ms') self.addLink( S8 , S9, bw=1000, delay='1.71322726ms') self.addLink( S8 , S11, bw=1000, delay='0.2409477ms') self.addLink( S9 , S10, bw=1000, delay='1.343440256ms') self.addLink( S10 , S11, bw=1000, delay='0.544934977ms') Сравнение контроллеров для построения сети В данный момент, существует большое количество платных и бесплатных(открытых) контроллеров. Все нижеперечисленные можно скачать и установить на домашнюю систему или виртуальную машину. Рассмотрим самые популярные открытые контроллеры и их плюсы и минусы: NOX - один из первых контроллеров, написан на языке C++; POX - контроллер, похожий на NOX и написанный на языке Python; OpenDayLight- контроллер, поддерживаемый многими корпорациями, написан на языке Java и постоянно развивающийся; RunOS- российская разработка от Центра Прикладного Исследования Компьютерных Сетей (ЦПИКС), имеет графический интерфейс, подробную документацию и заявлена самая высокая производительность. В таблице ниже рассмотрим плюсы и минусы каждого из контроллеров: Название контроллера Достоинства Недостатки NOX Скорость работы Низкое количество документации, необходимость знания C++ POX Проще обучиться, много документации Низкая скорость работы, необходимость знания Python, сложная реализация совместимости с NFV OpenDayLight Наличие графического интерфейса, поддержка VTN-сетей(NFV), наличие коммерческих продуктов на базе данного контроллера(Cisco XNC) Сложность в использовании, сложная установка RunOS Высокая производительность, Российская разработка, Открытый код, Наличие графического интерфейса Ранняя версия, возможные проблемы в эксплуатации по причине сырости продукта.
img
Уже прошло несколько лет с тех пор, как появился Kotlin, и он преуспевает. Так как Kotlin был создан в качестве замены Java, то его, как и следовало ожидать, во многом сравнивают именно с ним. Чтобы помочь вам выбрать один из двух языков, я сравню основные аспекты каждого из них.  Вот 8 пунктов, которые я рассмотрю в этой статье: Синтаксис Лямбда-выражения Обработка нулей Классы предметной области Глобальные переменные Параллелизм Функции расширения Сообщество Сравнение синтаксиса Давайте сначала проведем сравнение базового синтаксиса. Я думаю, что многие из вас, кто читает эту статью, возможно, уже знают кое-что о Java и/или Kotlin, но я все же приведу пример, чтобы мы могли явно их сравнить: Java public class HelloClass { public void FullName(String firstName, String lastName) {    String fullName = firstName + " " + lastName; System.out.println("My name is : " + fullName); }       public void Age() { int age = 21; System.out.println("My age is : " + age); } public static void main(String args[]) { HelloClass hello = new HelloClass(); hello.FullName("John","Doe");        hello.Age(); } } Kotlin class NameClass {    fun FullName(firstName: String, lastName:String) {        var fullName = "$firstName $lastName"        println("My Name is : $fullName")    } } fun Age() { var age : Int    age = 21    println("My age is: $age") } fun main(args: Array) {    NameClass().FullName("John","Doe")    Age() } Код не сильно отличается, если не считать небольших различий в синтаксисе методов и классов. Но реальное различие заключается в том, что Kotlin поддерживает вывод типов, где тип переменной не нужно объявлять. А еще там не нужны точки с запятой ( ; ). Также можно отметить, что Kotlin не сильно придерживается принципов ООП, в отличие от Java, где все содержится внутри класса. Посмотрите хотя бы на функции Age и main в примере – они не находятся внутри класса. Kotlin, как правило, имеет меньше строк кола, а вот Java придерживается традиционного подхода и, соответственно, является достаточно многословным.  Одно из преимуществ Kotlin перед Java – он может делать все, используя как традиционный ООП-подход, так и любой другой.  Лямбда-выражения Если мы заговорили о Java и Kotlin, то мы, конечно же, должны поговорить об их знаменитых лямбда-выражениях. У Kotlin есть встроенная поддержка лямбда-функций (и всегда была), а вот в Java она появилась только в Java 8.  Давайте посмотрим, как они выглядят. Java //syntaxes parameter -> expression (parameter1, parameter2) -> { code } //sample usage ArrayList numbers = new ArrayList(); numbers.add(5); numbers.add(9); numbers.forEach( (n) -> { System.out.println(n); } ); Kotlin //syntax { parameter1, parameter2 -> code } //sample usage max(strings, { a, b -> a.length < b.length }) В Java скобки не являются обязательными: если есть только один параметр, то они не нужны. Но в Kotlin скобки нужны всегда. Однако, в общем и целом, помимо синтаксиса, различий не так уж и много.  Как по мне, лямбда-функции используются только в качестве методов обратного вызова. Хоть они и имеют гораздо более широкий спектр применений, все же они не очень читабельны, в связи с чем их реже используют. Они, конечно, сократят объем вашего кода, но разобраться в нем потом будет достаточно сложно.  Это вопрос предпочтений, но мне кажется, что намного удобнее, когда скобки используются всегда, как в Kotlin, потому что так код становится более читабельным.  Обработка нулей В объектно-ориентированном языке значения нулевого типа всегда были проблемой. Когда вы пытаетесь использовать содержимое нулевого значения, выпадает исключение нулевого указателя (NPE - Null Pointer Exception). Поскольку NPE всегда были проблемой, то и у Java, и у Kotlin есть свой способ обработки нулевых объектов. Как они это делают, я покажу ниже.  Java Object object = objServ.getObject(); //traditional approach of null checking if(object!=null){    System.out.println(object.getValue()); } //Optional was introduced in Java 8 to further help with null values //Optional nullable will allow null object Optional objectOptional = Optional.ofNullable(objServ.getObject()); //Optional.of - throws NullPointerException if passed parameter is null Optional objectNotNull = Optional.of(anotherObj); if(objectOptional.isPresent()){    Object object = objectOptional.get();    System.out.println(object.getValue()); } System.out.println(objectNotNull.getValue()); Kotlin  //Kotlin uses null safety mechanism var a: String = "abc" // Regular initialization means non-null by default a = null // compilation error //allowing null only if it is set Nullable var b: String? = "abc" // can be set null b = null // ok print(b) Сколько себя помню, в Java использовалась обычная проверка нулей, которой свойственен человеческий фактор. Затем в Java 8 появились необязательные классы, которые создают возможность для более надежной проверки нулевых значений, особенно со стороны API/сервера.  А вот Kotlin, если переменная допускает возможность нулевого значения, позволяет использовать операторы безопасного вызова. Я еще не пользовался необязательным классом, но, мне кажется, что его механизм работы и назначение чем-то похожи на операторы безопасного вызова в Kotlin. Оба варианта помогают определить, какая переменная может быть нулевой, и убедиться, что была реализована корректная проверка.  Иногда в коде может быть много переменных, которые надо проверить, и их слишком много для того, чтобы проверить их все. Но если вы будете добавлять проверки везде, где нужно, это сделает нашу кодовую базу просто безобразной, а это, я думаю, никому не понравится, так ведь? На мой взгляд, использование необязательных классов Java ощущается более сложным из-за объема кода, который надо добавить. А вот в Kotlin можно просто добавить немного кода, который будет проверять нулевые значения за вас.  Класс предметной области Некоторые называют это классом-сущностью. Ниже я привел примеры того, как классы используются в качестве классов предметной области в каждом языке. Java public class Student {     private String name;     private Integer age;         // Default constructor public Student() { }     public void setName(String name) {         this.name = name;     }     public String getName() {         return name;     }         public void setAge(Integer age) {         this.age = age;     }     public Integer getAge() {         return age;     } } Kotlin //Kotlin data class data class Student(var name: String = "", var age: Int = 0) //Usage var student: Student = Student("John Doe", 21) В Java свойства объявляются как частные (private) в соответствии с технологией инкапсуляции. Когда вы пытаетесь получить доступ к этим свойствам, Java использует сеттеры и геттеры, а также методы isEqual или toString, когда это необходимо. В Kotlin классы данных вводятся для определенных целей классов предметной области. Классы данных обеспечивают прямой доступ к свойствам. Они также предоставляют несколько встроенных служебных методов, таких как equals(), toString() и copy(). Я считаю, что классы данных — одна из лучших вещей, которые предлагает Kotlin. Они стремятся уменьшить количество шаблонного кода, который требуется для обычных классов предметной области, и они хорошо справляются с этой задачей. Случайное фото… потому что вы уже на полпути! Глобальные переменные Иногда может возникнуть необходимость создать такую переменную, которая была бы доступна в вашей кодовой базе везде. Для этого существуют глобальные переменные. Kotlin и Java имеют свои способы решения этой проблемы.  Java public class SomeClass { public static int globalNumber = 10; } //can be called without initializing the class SomeClass.globalNumber; Kotlin class SomeClass {    companion object {        val globalNumber = 10    } } //called exactly the same like usual SomeClass.globalNumber Некоторые из вас, возможно, уже знакомы с ключевым словом static, которое используется в некоторых других языках, таких как C++. Оно инициализируется в начале выполнения программы, и Java использует его для создания глобальных переменных, так как оно не содержится в качестве объекта. Это значит, что к нему можно получить доступ откуда угодно без инициализации класса как объекта.  Kotlin использует здесь совершенно иной подход: он убирает ключевое слово static и заменяет его объектом-компаньоном, который очень похож на одноэлементный класс. Это позволяет реализовывать сложные функциональные средства, такие как расширения и интерфейсы. То, что в Kotlin отсутствует ключевое слово static, застало меня врасплох. Вы, конечно, можете возразить, что использование ключевого слова static не самый удачный подход из-за его природы и сложности его проверки, и что, конечно же, объект-компаньон в Kotlin может легко его заменить. Даже в таком случае использование static для глобальной переменной не должно быть слишком сложным. Если мы будем осторожны с глобальными переменными и не сделаем для себя привычкой создавать их постоянно, то у нас все будет в порядке. Объект-компаньон также может дать нам некоторую гибкость при взаимодействии и т.п., но как часто мы будем взаимодействовать с одноэлементными классами? Я думаю, что ключевые слова static помогают нам сохранять краткость и ясность в отношении глобальных переменных. Параллелизм В наши дни параллелизм является популярной темой для обсуждения. Иногда способность языка программирования выполнять несколько задач одновременно может стать решающим критерием при выборе языка.  Теперь давайте посмотрим, как эти два языка решают эту задачу. Java // Java code for thread creation by extending // the Thread class class MultithreadingDemo extends Thread {    public void run()    {        try        {            // Displaying the thread that is running            System.out.println ("Thread " +                  Thread.currentThread().getId() +                  " is running");        }        catch (Exception e)        {            // Throwing an exception            System.out.println ("Exception is caught");        }    } } // Main Class public class Multithread {    public static void main(String[] args)    {        int n = 8; // Number of threads        for (int i=0; i) {    var number = 1    var result = number.plusOne()    println("Result is: $result") } Они позволяют добавить в класс новую функцию, при этом она не будет распространяться на класс или не нужно будет использовать какие-то замысловатые шаблоны проектирования. Она даже позволяет вам добавить функцию к изменяемому классу Kotlin. Вы практически можете попрощаться с тем самым методом lib, который требует, чтобы вы передавали все внутри своих параметров. Сообщество И последнее, но оттого не менее важное: давайте поговорим о чем-то нетехнического характера. Во-первых, давайте посмотрим на результаты опроса, которые отображают наиболее часто используемые языки программирования в 2020 году.  Здесь можно видеть, что одним из наиболее часто используемых языков является Java. И несмотря на то, что Kotlin все еще набирает обороты, сообщество Java все же в несколько раз больше, чем сообщество Kotlin, и, скорее всего, в ближайшее время это не сильно изменится.  Тогда какое это имеет значение? На самом деле имеет, и большое. Так как у Java большое сообщество, то тем, кто работает с Java, гораздо легче найти ссылки или получить помощь, когда это необходимо, как в Интернете, так и в реальной жизни.  Многие компании все еще используют Java в качестве основы, и это может так и остаться в ближайшее время, даже с учетом того, что Kotlin совместим с Java. Обычно переход на новые технологии не происходит для какой-либо одной бизнес-цели, только если у компании нет для этого действительно серьезных оснований.  Подведем итог Для тех, кто решил просто прочитать краткое изложение, вот что мы обсудили: синтаксис: структуры не сильно отличаются, разве что в некоторых мелочах, но Kotlin более гибкий в некоторых моментах; лямбда-выражения: синтаксис практически одинаковый, но Kotlin использует фигурные скобки для того, чтобы код было удобнее читать; обработка нулей: для того, чтобы обработку нулевых значений, Java использует класс, а Kotlin – встроенные операторы безопасных вызовов; классы предметной области: Java использует классы с частными переменными и геттерами/сеттерами, а Kotlin обеспечивает их работу с помощью классов данных; глобальные переменные: Java использует ключевое слово static, а Kotlin – что-то на подобие подклассов; параллелизм: Java использует многопоточность, а Kotlin – сопрограммы (которые обычно более легковесные); функции расширения: это новая функция, введенная в Kotlin, которая позволяет легко добавлять функции в классы, при этом не расширяя их; сообщество: здесь Java по-прежнему лидирует, что помогает в его изучении и получении необходимой помощи. Есть множество других особенностей, которые мы могли бы сравнить. Но то, что мы здесь уже обсудили, я считаю, является основным и самым важным.  На сегодняшний день, я думаю, Kotlin стоит того, чтобы обратить на него внимание. С точки зрения разработки, это поможет избавиться от длинного шаблонного кода и сделать его понятным и коротким. Если вы уже программируете на Java, то изучение Kotlin должно легко вам даться, и вы можете с этим не спешить. 
img
Вопрос о балансировке нагрузки на WAN-линках встает довольно часто, и, к сожалению, в отличие от некоторых других вещей, которые можно настроить на оборудовании MikroTik быстро и безболезненно - в случае настройки Load Balancing придется немного постараться. Тема относительно сложная, наличие нескольких WAN-линков и задача по настройке балансировки нагрузки включает в себя настройку нескольких шлюзов и маршрутов по умолчанию, множество правил трансляции NAT и так далее. Настройка маршрутизатора Итак, в наличие у нас имеется один маршрутизатор MikroTik, который подключен к двум провайдерам - Тарс Телеком и Милайн на портах ether1 и ether2 соответственно, и локальной сетью на порту ether3. Трафик из локальной сети будет NATирован из обоих WAN портов и будет сбалансирован по нагрузке. Топология ниже: Настраиваем локальные IP-адреса: /ip address add address=1.1.1.199/24 interface=ether1 comment="Tars" add address=2.2.2.199/24 interface=ether2 comment="Meeline" add address=192.168.1.1/24 interface=ether3 comment="LAN Gateway" Настраиваем шлюзы по умолчанию: /ip route add dst-address=0.0.0.0/0 check-gateway=ping gateway=1.1.1.1,2.2.2.1 Настраиваем NAT на WAN портах для исходящего направления: /ip firewall nat add action=masquerade chain=srcnat comment="Tars" out-interface=ether1 add action=masquerade chain=srcnat comment="Meeline" out-interface=ether2 Если на данном этапе перестать настраивать роутер, то это будет являть собой пример настройки отказоустойчивости. Если один из линков “отвалится”, то вместо него будет использоваться второй. Однако, никакой балансировки нагрузки здесь нет и в помине, и, с экономической точки зрения, это является плохой идеей - вряд ли найдется компания, которая захочет платить абонентскую плату за второй канал и использовать его только в случае аварии. Исходящая и входящая Mangle маркировка Одной из типичных проблем при использовании более одного WAN-соединения является то, что пакеты принятые на одном WAN интерфейсе, могут тут же быть отправлены через другой WAN-интерфейс, что может, к примеру, сломать VPN-based сеть. Нам нужно чтобы пакеты “принадлежащие” одному и тому же соединению принимались и отправлялись через один и тот же WAN порт. В случае аварии у одного из провайдеров, все подключения на порту “умрут” и затем будут переподключены на другом WAN порту. Для этого необходимо промаркировать соединения: /ip firewall mangle add action=mark-connection chain=input comment="Tars Input" in-interface=ether1 new-connection-mark="Tars Input" add action=mark-connection chain=input comment="Meeline Input" in-interface=ether2 new-connection-mark="Meeline Input" Это поможет маршрутизатору отслеживать порт для каждого входящего подключения. Теперь мы будем использовать отметку подключения для входящих пакетов для вызова отметки маршрутизации. Это отметка маршрутизации будет использована позднее на маршруте, который будет сообщать подключению через какой WAN-порт необходимо слать пакеты наружу. add action=mark-routing chain=output comment="Tars Output" connection-mark="Tars Input" new-routing-mark="Out Tars" add action=mark-routing chain=output comment="Meeline Output" connection-mark="Meeline Input" new-routing-mark="Meeline Telecom" Помеченные подключения затем получают метку маршрута, так что роутер сможет маршрутизировать пакеты так, как нам необходимо. В следующем шаге мы настроим роутер таким образом, чтобы помеченные пакеты отправлялись наружу из корректного WAN-подключения. Маркировка LAN маршрута Понадобится также настроить несколько Mangle правил - они необходимы, чтобы сообщить роутеру о необходимости балансировки пакетов, которые отправляются из локальной сети. Сам механизм балансировки в этой статье не описывается, можно только сказать что происходить много операций хеширования - если же интересно копнуть глубже, то вы можете обратиться к официальной документации MikroTik. В соответствии с этими правилами маршрутизатор будет балансировать трафик приходящий на порт ether3 (LAN-порт), который направлен на любой нелокальный адрес в Интернете. Мы захватываем трафик в цепочке предварительной маршрутизации для перенаправления его на необходимый нам WAN-порт в соответствии с меткой маршрутизации. Следующие команды балансируют трафик на LAN-интерфейсе через две группы: add action=mark-routing chain=prerouting comment="LAN load balancing 2-0" dst-address-type=!local in-interface=ether3 new-routing-mark= "Out Tars" passthrough=yes per-connection-classifier= both-addresses-and-ports:2/0 add action=mark-routing chain=prerouting comment="LAN load balancing 2-1" dst-address-type=!local in-interface=ether3 new-routing-mark= "Out Meeline" passthrough=yes per-connection-classifier= both-addresses-and-ports:2/1 Настройка меток маршрутизации выше была выполнена точно такие же как и в предыдущем шаге и соответствуют тем маршрутам, которые будут созданы в следующем шаге. Особые маршруты по умолчанию. В данный момент у нас должны быть помечены соединения поступающие на WAN-порты и эти метки были использованы для создания меток маршрутизации. Балансировка нагрузки в LAN, описанная в предыдущем шаге, также создает метки маршрутизации в соответствии со следующим шагом, в котором будут созданы маршруты по умолчанию, которые будут захватывать трафик с данными метками маршрутизации. /ip route add distance=1 gateway=1.1.1.1 routing-mark="Out Tars" add distance=1 gateway=2.2.2.1 routing-mark="Out Meeline" Данные маршруты используются только при наличии необходимой метки маршрутизации. Непомеченные пакеты используют обычный маршрут по умолчанию. Маршруты, относящиеся к Тарс Телеком получают метку подключения, которая вызывает метку маршрутизации. Эта метка маршрутизации совпадает с меткой в маршруте выше и обратный пакет выходит из того же интерфейса, на котором был получен изначальный пакет. Заключение Итого, какие шаги по настройке роутера были выполнены: Маркировка новых подключений в WAN Соединения с этой маркировкой получают метку маршрутизации Исходящий из локальной сети трафик балансируется с теми же метками маршрутизации Метки маршрутизации соответствуют маршрутам по умолчанию и отправляются из соответствующего интерфейса Если количество WAN-линков более 2 - необходимо проделать такие же действия для остальных подключений. Итого, теперь у вас настроена балансировка трафика для двух WAN-соединений.
ВЕСЕННИЕ СКИДКИ
40%
50%
60%
До конца акции: 30 дней 24 : 59 : 59