portaldacalheta.pt
  • Основен
  • Инженерно Управление
  • Мобилен Дизайн
  • Разпределени Екипи
  • Пъргав
Back-End

Оптимизирана софтуерна интеграция: Урок за Apache Camel



Софтуерът рядко, ако изобщо изобщо, има информационен вакуум. Поне това е предположението, което софтуерните инженери могат да направят за повечето приложения, които разработваме.

Във всякакъв мащаб всяка част от софтуера - по един или друг начин - комуникира с друг софтуер по различни причини: за получаване на референтни данни от някъде, за изпращане на сигнали за наблюдение, за поддържане на връзка с други услуги, докато е част от разпределена система и още.



Apache Camel за оптимизирана софтуерна интеграция



В този урок ще научите за някои от най-големите предизвикателства при интегрирането на голям софтуер и как Apache Camel ги решава с лекота.



Проблемът: Архитектурен дизайн за системна интеграция

Може да сте направили следното поне веднъж в живота на софтуерното инженерство:

  • Определете част от бизнес логиката, която трябва да започнете да изпращате данни.
  • В същия слой на приложението напишете трансформациите на данни според очакванията на получателя.
  • Той обгръща данните в структура, която е подходяща за прехвърляне и маршрутизиране през мрежа.
  • Отворете връзка с целево приложение, като използвате подходящ SDK на драйвер или клиент.
  • Изпратете данните и обработете отговора.

Защо това е лош начин на действие?



Въпреки че имате само няколко такива връзки, тя все още е управляема. С нарастващия брой връзки между системите бизнес логиката на приложението се смесва с интеграционната логика, която се опитва да адаптира данните, да компенсира технологичните разлики между две системи и да прехвърли данни към външната система със SOAP, REST или по-екзотични заявки.

Ако интегрирате множество приложения, би било невероятно трудно да се преначертае пълната картина на зависимостите в такъв код: Къде се произвеждат данните и какви услуги ги консумират? Ще имате много места, където логиката на интеграция се дублира, за да се зареди.



С този подход, въпреки че задачата е технически изпълнена, ние имаме големи проблеми с поддържаемостта и мащабируемостта на интеграцията. Бързата реорганизация на потоците от данни в тази система е почти невъзможна, да не говорим за по-дълбоки проблеми като липса на мониторинг, прекъсване на веригата, трудоемко извличане на данни и т.н.

Това е особено важно при интегриране на софтуер в обхвата на значително голяма компания. Адресирането на бизнес интеграцията означава работа с набор от приложения, които работят на широк спектър от платформи и са разположени на различни места. Обменът на данни в такава софтуерна среда е доста взискателен. Той трябва да отговаря на високите индустриални стандарти за сигурност и да осигурява надежден начин за прехвърляне на данни. В корпоративна среда системната интеграция изисква отделен и изцяло доработен архитектурен дизайн.



Тази статия ще ви запознае с уникалните трудности, пред които е изправена интеграцията на софтуера, и ще предостави някои базирани на опит решения за интеграционни задачи. Ще се запознаем с Apache Camel , полезна рамка, която може да облекчи най-лошите аспекти на главоболието на разработчика на интеграция. Ще продължим с пример за това как Camel може да помогне за установяването на комуникация в клъстер от микроуслуги, задвижвани от Kubernetes.

Трудности при интеграцията

Широко използван подход за решаване на проблема е отделянето на интеграционен слой във вашето приложение. Може да съществува в самото приложение или като специален софтуер, който работи независимо - в последния случай се нарича междинен софтуер .



С какви проблеми се сблъсквате обикновено при разработване и поддържане междинен софтуер ? Като цяло той има следните ключови елементи:

какъв език за програмиране използва роботиката
  • Всички канали за данни са ненадеждни до известна степен. Проблеми, произтичащи от тази ненадеждност, може да не възникнат, докато интензивността на данните е ниска или умерена. Всяко ниво на съхранение от паметта на приложенията до по-ниския кеш и оборудването по-долу е обект на потенциална повреда. Някои редки грешки възникват само при големи обеми данни. Дори зрелите продукти от готови за производство доставчици имат нерешени проблеми с проследяването на грешки, свързани със загубата на данни. Система от междинен софтуер Той трябва да може да ви информира за тези жертви на данни и да препрати съобщението за предоставяне своевременно.



  • Приложенията използват различни протоколи и формати на данни. Това означава, че интеграционната система е завеса за трансформация на данни и адаптери за други участници и използва разнообразни технологии. Те могат да включват прости извиквания на REST API, но също така могат да имат достъп до посредник на опашки, да изпращат CSV команди чрез FTP или да извличат групови данни към таблица на базата данни. Това е дълъг списък и той никога няма да бъде съкратен.

  • Промените във форматите на данните и правилата за маршрутизиране са неизбежни. Всяка стъпка в процеса на разработка на приложение, която променя структурата на данните, обикновено води до промени във форматите за преобразуване на данни и трансформациите. Понякога са необходими промени в инфраструктурата с реорганизирани потоци от данни на компанията. Например тези промени могат да възникнат, когато се въведе една точка за проверка на референтни данни, която трябва да обработи всички записи на основните данни във фирмата. Със системите N можем да получим максимум почти връзки N^2 между тях, така че броят на местата, където трябва да се приложат промени, нараства доста бързо. Ще бъде като лавина. За да се запази поддръжката, слой от междинен софтуер трябва да предоставите ясна картина на зависимостите с гъвкаво маршрутизиране и трансформация на данни.

Тези идеи трябва да бъдат взети предвид при проектирането на интеграцията и избора на решение за междинен софтуер по-подходящо. Един от възможните начини за справяне с него е да се възползвате от автобус за бизнес услуги ( ESB ). Но ESB предоставени от големите доставчици обикновено са твърде тежки и често много обезпокоителни - почти невъзможно е да започнете бързо с a ESB , той има доста стръмна крива на обучение и неговата гъвкавост се жертва на дълъг списък от вградени функции и инструменти. Според мен леките решения за интеграция с отворен код са далеч по-добри: те са по-еластични, лесни за внедряване в облака и лесни за мащабиране.

Софтуерната интеграция не е лесна за изпълнение. Днес, докато изграждаме архитектури на микроуслуги и се справяме с рояци от малки услуги, ние също имаме големи очаквания за това колко ефективно те трябва да комуникират.

Модели за бизнес интеграция

Както можете да очаквате, подобно на разработката на софтуер като цяло, трансформацията на данни и разработването на маршрутизация включва повтарящи се операции. Опитът в тази област е обобщен и систематизиран от професионалисти, които от доста време се занимават с интеграционни проблеми. В изхода има набор от извлечени шаблони, наречени модели на бизнес интеграция използва се за проектиране на потоци от данни. Тези методи за интеграция са описани в едноименната книга от Грегор Хоф и Боби Улф, която много прилича на значимата книга „Банда на четири“, но в областта на залепването на софтуер.

За да даде пример, шаблонът на нормализатора въвежда компонент, който семантично картографира едни и същи съобщения, които имат различни формати на данни, в един каноничен модел, или агрегаторът е EIP, който комбинира поредица от съобщения в едно.

Тъй като те са технологично независими абстракции, използвани за решаване на архитектурни проблеми, EIPs помагат да се напише архитектурен дизайн, който не се задълбочава на ниво код, а описва потоците от данни достатъчно подробно. Подобна нотация за описание на интеграционните пътища не само прави дизайна сбит, но също така установява обща номенклатура и общ език, които са много важни в контекста на решаването на задача за интеграция с членове на екипа от различни търговски области

Представяме ви Apache Camel

Преди няколко години изграждах корпоративна интеграция в голяма мрежа за хранителни магазини с магазини на широко разпространени места. Започнах с патентовано решение на ESB което се оказа твърде тромаво за поддържане. Така нашият екип се натъкна на Apache Camel и след като извършихме работа с „доказателство за концепция“, бързо пренаписахме всички наши потоци от данни по маршрутите на Camel.

Apache Camel може да се опише като 'рутер за посредничество', рамка на междинен софтуер ориентиран към съобщения, който изпълнява списъка на EIP , с които се запознах. Той използва тези модели, поддържа всички общи транспортни протоколи и има богат набор от полезни адаптери. Camel позволява обработката на поредица от интеграционни процедури, без да е необходимо да пишете свой собствен код.

как да използвате google glass

Отделно от това, бих подчертал следните характеристики на Apache Camel:

  • Пътищата за интеграция са написани като тръби, направени от блокове. Създава напълно прозрачно изображение, което помага за проследяване на потоците от данни.
  • Camel има адаптери за много популярни API. Например получаване на данни от Apache Kafka, наблюдение на AWS EC2 екземпляри, интегриране с Salesforce - всички тези задачи могат да бъдат решени с помощта на наличните готови компоненти.

Маршрутите на Apache Camel могат да бъдат написани на Java или Scala DSL. (Предлага се и XML конфигурация, но тя става твърде подробна и има по-лоши възможности за отстраняване на грешки.) Това не налага ограничения върху технологичния стек на комуникационните услуги, но ако пишете на Java или Scala, можете да вградите Camel в приложение, вместо да го стартирате самостоятелно.

Обозначението на маршрута, използвано от Camel, може да бъде описано със следния прост псевдокод:

from(Source) .transform(Transformer) .to(Destination)

Fuente, Transformador И Destino са крайните точки, които се отнасят до компонентите за изпълнение чрез техните URI.

Какво позволява на Camel да разреши проблемите с интеграцията, които описах по-горе? Нека да разгледаме. На първо място, логиката за маршрутизиране и преобразуване вече се намира само в специална конфигурация на Apache Camel. Второ, чрез краткия и естествен DSL, заедно с използването на EIP, се появява картина на зависимостите между системите. Той е направен от разбираеми абстракции и логиката на маршрутизиране е лесно регулируема. И накрая, не е нужно да пишем много код за преобразуване, защото подходящите адаптери вероятно вече са включени.

Интеграции

Трябва да добавя, че Apache Camel е зряла рамка и получава редовни актуализации. Има голяма общност и значителна натрупана база знания.

Той има свои собствени недостатъци. Камилата не трябва да се приема като сложен интеграционен пакет. Това е набор от инструменти без функции на високо ниво като инструменти за управление на бизнес процеси или монитори на дейности, но може да се използва за създаване на такъв софтуер.

Алтернативни системи могат да бъдат например Spring Integration или Mule ESB . За Spring Integration, макар да се счита за лек, според моя опит съставянето и писането на много XML конфигурационни файлове може да бъде неочаквано сложно и не лесен изход. Муле ESB Това е здрав и изключително функционален набор от инструменти, но както подсказва името, това е корпоративна сервизна шина, така че принадлежи към различен тегловен клас. Mule може да се сравни с Fuse ESB , подобен продукт, базиран на Apache Camel с богат набор от функции. За мен използването на Apache Camel за поставяне на услуги в днешно време е очевидна задача. Той е лесен за използване и дава ясно описание на случващото се, като същевременно е достатъчно функционален, за да изгради сложни интеграции.

Напишете примерен маршрут

Нека започнем да пишем кода. Ще започнем със синхронен поток от данни, който насочва съобщенията от един източник към списък с получатели. Правилата за маршрутизиране ще бъдат написани на Java DSL .

Ние ще използваме Мейвън за изграждане на проекта. Първо добавете следната зависимост към pom.xml:

... org.apache.camel camel-core 2.20.0

Алтернативно, приложението може да бъде изградено върху camel-archetype-java архетипа.

Определенията за камилски път са декларирани по метода RouteBuilder.configure

public void configure() { errorHandler(defaultErrorHandler().maximumRedeliveries(0)); from('file:orders?noop=true').routeId('main') .log('Incoming File: ${file:onlyname}') .unmarshal().json(JsonLibrary.Jackson, Order.class) // unmarshal JSON to Order class containing List .split().simple('body.items') // split list to process one by one .to('log:inputOrderItem') .choice() .when().simple('${body.type} == 'Drink'') .to('direct:bar') .when().simple('${body.type} == 'Dessert'') .to('direct:dessertStation') .when().simple('${body.type} == 'Hot Meal'') .to('direct:hotMealStation') .when().simple('${body.type} == 'Cold Meal'') .to('direct:coldMealStation') .otherwise() .to('direct:others'); from('direct:bar').routeId('bar').log('Handling Drink'); from('direct:dessertStation').routeId('dessertStation').log('Handling Dessert'); from('direct:hotMealStation').routeId('hotMealStation').log('Handling Hot Meal'); from('direct:coldMealStation').routeId('coldMealStation').log('Handling Cold Meal'); from('direct:others').routeId('others').log('Handling Something Other'); }

В тази дефиниция създаваме маршрут, който извлича записите от JSON файла, разделя ги на елементи и насочва към набор от контролери въз основа на съдържанието на съобщението.

Нека го пуснем на подготвените тестови данни. Ще получим изхода:

INFO | Total 6 routes, of which 6 are started INFO | Apache Camel 2.20.0 (CamelContext: camel-1) started in 10.716 seconds INFO | Incoming File: order1.json INFO | Exchange[ExchangePattern: InOnly, BodyType: com.antongoncharov.camel.example.model.OrderItem, Body: OrderItem{id='1', type='Drink', name='Americano', qty='1'}] INFO | Handling Drink INFO | Exchange[ExchangePattern: InOnly, BodyType: com.antongoncharov.camel.example.model.OrderItem, Body: OrderItem{id='2', type='Hot Meal', name='French Omelette', qty='1'}] INFO | Handling Hot Meal INFO | Exchange[ExchangePattern: InOnly, BodyType: com.antongoncharov.camel.example.model.OrderItem, Body: OrderItem{id='3', type='Hot Meal', name='Lasagna', qty='1'}] INFO | Handling Hot Meal INFO | Exchange[ExchangePattern: InOnly, BodyType: com.antongoncharov.camel.example.model.OrderItem, Body: OrderItem{id='4', type='Hot Meal', name='Rice Balls', qty='1'}] INFO | Handling Hot Meal INFO | Exchange[ExchangePattern: InOnly, BodyType: com.antongoncharov.camel.example.model.OrderItem, Body: OrderItem{id='5', type='Dessert', name='Blueberry Pie', qty='1'}] INFO | Handling Dessert

Както се очакваше, Камила изпрати съобщения до дестинации.

Опции за трансфер на данни

В предишния пример взаимодействието между компонентите е синхронно и се осъществява чрез паметта на приложението. Има обаче много повече начини за комуникация, когато обработваме отделни приложения, които не споделят памет:

  • Споделяне на файлове. Едното приложение създава споделени файлове с данни, което другото може да консумира. Там живее духът на старото училище. Този метод на комуникация има множество последствия: липса на транзакции и последователност, лоша производителност и изолирана координация между системите. Много разработчици в крайна сметка написаха домашни интеграционни решения, за да направят процеса повече или по-малко управляем.
  • Обща база данни. Нека приложенията съхраняват данните, които искат да споделят, в обща схема на една база данни. Проектирането на единна схема и обработката на едновременен достъп до таблици са най-големите предизвикателства в този подход. Както при споделянето на файлове, лесно е това да се превърне в постоянно тясно място.
  • Отдалечено извикване на API. Осигурява интерфейс, който позволява на приложението да взаимодейства с друго работещо приложение, като типично извикване на метод. Приложенията споделят функционалност чрез API извиквания, но вие ги свързвате тясно в процеса.
  • Messenger услуга. Нека всяко приложение да се свърже с обща система за съобщения и да обменя данни и да извиква поведение асинхронно чрез съобщения. Нито изпращачът, нито получателят трябва да работят едновременно, за да доставят съобщението.

Има повече начини за взаимодействие, но трябва да имаме предвид, че като цяло има два вида взаимодействие: синхронно и асинхронно. Първият е като извикване на функция във вашия код - потокът на изпълнение ще чака, докато тя се изпълни и върне стойност. При асинхронен подход същите данни се изпращат през междинна опашка от съобщения или тема за абонамент. Можете да приложите асинхронно отдалечено извикване на функция като EIP заявка-отговор .

Асинхронните съобщения обаче не са лек; предполага определени ограничения. Рядко виждате API за съобщения в мрежата; Синхронните REST услуги са много по-популярни. Но междинен софтуер Съобщенията се използват широко в корпоративната интранет или разпределена системна вътрешна инфраструктура.

Използване на опашки за съобщения

Нека направим нашия асинхронен пример. Извиква се софтуерна система, която управлява опашки за абонамент и теми агент за съобщения . Това е като a Свързана система за управление на база данни ( RDBMS ) за таблици и колони. Опашките функционират като peer-to-peer интеграция, докато темите са за публикуване-абонаментна комуникация с много получатели. Ние ще използваме Apache ActiveMQ като посредник за съобщения в JMS, защото е надежден и може да се вгражда.

Добавете следната зависимост. Понякога е прекомерно да добавяте activemq-all, който съдържа всички ActiveMQ Jar файлове, към проекта, но ние ще запазим зависимостите на приложението си без усложнения.

org.apache.activemq activemq-all 5.15.2

След това стартирайте брокера програмно. В Spring Boot имаме автоматична конфигурация за това, когато свързваме зависимостта Maven. spring-boot-starter-activemq.

Стартирайте нов посредник за съобщения със следните команди, като посочите само крайната точка на конектора:

BrokerService broker = new BrokerService(); broker.addConnector('tcp://localhost:61616'); broker.start();

И добавете следния конфигурационен фрагмент към тялото на метода configure

ConnectionFactory connectionFactory = new ActiveMQConnectionFactory('tcp://localhost:61616'); this.getContext().addComponent('activemq', ActiveMQComponent.jmsComponent(connectionFactory));

Сега можем да актуализираме предишния пример, като използваме опашки за съобщения. Опашките ще се създават автоматично при доставка на съобщение.

какво е Adobe xd cc
public void configure() { errorHandler(defaultErrorHandler().maximumRedeliveries(0)); ConnectionFactory connectionFactory = new ActiveMQConnectionFactory('tcp://localhost:61616'); this.getContext().addComponent('activemq', ActiveMQComponent.jmsComponent(connectionFactory)); from('file:orders?noop=true').routeId('main') .log('Incoming File: ${file:onlyname}') .unmarshal().json(JsonLibrary.Jackson, Order.class) // unmarshal JSON to Order class containing List .split().simple('body.items') // split list to process one by one .to('log:inputOrderItem') .choice() .when().simple('${body.type} == 'Drink'') .to('activemq:queue:bar') .when().simple('${body.type} == 'Dessert'') .to('activemq:queue:dessertStation') .when().simple('${body.type} == 'Hot Meal'') .to('activemq:queue:hotMealStation') .when().simple('${body.type} == 'Cold Meal'') .to('activemq:queue:coldMealStation') .otherwise() .to('activemq:queue:others'); from('activemq:queue:bar').routeId('barAsync').log('Drinks'); from('activemq:queue:dessertStation').routeId('dessertAsync').log('Dessert'); from('activemq:queue:hotMealStation').routeId('hotMealAsync').log('Hot Meals'); from('activemq:queue:coldMealStation').routeId('coldMealAsync').log('Cold Meals'); from('activemq:queue:others').routeId('othersAsync').log('Others'); }

Добре, сега взаимодействието стана асинхронно. Потенциалните потребители на тази информация имат достъп до нея, когато са готови да го направят. Това е пример за слабо свързани, които се опитваме да постигнем в реактивна архитектура. Недостъпността на една от услугите няма да блокира останалите. Също така потребителят може паралелно да мащабира и чете от опашката. Самата опашка може да се мащабира и да бъде разделена. Постоянните опашки могат да съхраняват данни на диск, чакайки да бъдат обработени, дори когато всички участници са се сринали. Следователно тази система е по-устойчива на грешки.

Изненадващ факт е, че CERN използва Apache Camel и ActiveMQ за наблюдение на системите на Голям адронен колайдер ( LHC ) . Има и теза на интересен опит, който обяснява избора на решение на междинен софтуер подходящ за тази задача . Така че, както се казва в ключовата част, 'Без JMS - няма физика на частиците!'

Монитор

В предишния пример ние създаваме канала за данни между две услуги. Това е допълнителна потенциална точка на провал в една архитектура, така че трябва да се погрижим за нея. Нека да разгледаме функциите за наблюдение, които Apache Camel предлага. По принцип тя излага статистическа информация за вашите маршрути през MBeans, до които JMX има достъп. ActiveMQ излага статистиката на опашката по същия начин.

Ще включим JMX сървъра в приложението, за да му позволим да работи с опциите на командния ред:

-Dorg.apache.camel.jmx.createRmiConnector=true -Dorg.apache.camel.jmx.mbeanObjectDomainName=org.apache.camel -Dorg.apache.camel.jmx.rmiConnector.registryPort=1099 -Dorg.apache.camel.jmx.serviceUrlPath=camel

Сега стартирайте приложението, така че пътят да си свърши работата. Отваря стандартния инструмент jconsole и се свържете с процеса на кандидатстване. Свържете се с URL адреса service:jmx:rmi:///jndi/rmi://localhost:1099/camel. Отидете на домейна org.apache.camel в дървото MBeans.

Снимка на екрана 1

Виждаме, че всичко за маршрутизацията е под контрол. Имаме броя на съобщенията в полет, броя на грешките и броя на съобщенията в опашките. Тази информация може да бъде насочена към набор от високофункционални инструменти за мониторинг като Graphana или Kibana. Можете да направите това, като внедрите добре познатия стек ELK.

трябва ли да науча C или C++

Също така има добавима и разширяема уеб конзола, която осигурява потребителски интерфейс за управление на Camel, ActiveMQ и много други, наречен hawt.io .

Снимка на екрана 2

Маршрути за тестване

Apache Camel има доста широка функционалност за напишете тестови пътища с фалшиви компоненти . Това е мощен инструмент, но писането на отделни пътища само за тестване е отнемащ време процес. Би било по-ефективно да провеждате тестове по производствените маршрути, без да променяте конвейера си. Camel има тази функция и може да бъде реализирана с помощта на компонента Съвет С .

Ще включим тестова логика в нашия пример и ще стартираме примерен тест.

junit junit 4.11 test org.apache.camel camel-test 2.20.0 test

Тестовият клас е:

public class AsyncRouteTest extends CamelTestSupport { @Override protected RouteBuilder createRouteBuilder() throws Exception { return new AsyncRouteBuilder(); } @Before public void mockEndpoints() throws Exception { context.getRouteDefinition('main').adviceWith(context, new AdviceWithRouteBuilder() { @Override public void configure() throws Exception { // we substitute all actual queues with mock endpoints mockEndpointsAndSkip('activemq:queue:bar'); mockEndpointsAndSkip('activemq:queue:dessertStation'); mockEndpointsAndSkip('activemq:queue:hotMealStation'); mockEndpointsAndSkip('activemq:queue:coldMealStation'); mockEndpointsAndSkip('activemq:queue:others'); // and replace the route's source with test endpoint replaceFromWith('file://testInbox'); } }); } @Test public void testSyncInteraction() throws InterruptedException { String testJson = '{'id': 1, 'order': [{'id': 1, 'name': 'Americano', 'type': 'Drink', 'qty': '1'}, {'id': 2, 'name': 'French Omelette', 'type': 'Hot Meal', 'qty': '1'}, {'id': 3, 'name': 'Lasagna', 'type': 'Hot Meal', 'qty': '1'}, {'id': 4, 'name': 'Rice Balls', 'type': 'Hot Meal', 'qty': '1'}, {'id': 5, 'name': 'Blueberry Pie', 'type': 'Dessert', 'qty': '1'}]}'; // get mocked endpoint and set an expectation MockEndpoint mockEndpoint = getMockEndpoint('mock:activemq:queue:hotMealStation'); mockEndpoint.expectedMessageCount(3); // simulate putting file in the inbox folder template.sendBodyAndHeader('file://testInbox', testJson, Exchange.FILE_NAME, 'test.json'); //checks that expectations were met assertMockEndpointsSatisfied(); } }

Сега изпълнете тестове за приложението с mvn test. Виждаме, че нашият маршрут е изпълнен успешно със съветите за тестване. Няма съобщения, преминали през реалните опашки и тестовете са преминали.

INFO | Route: main started and consuming from: file://testInbox INFO | Incoming File: test.json INFO | Asserting: mock://activemq:queue:hotMealStation is satisfied

Използване на Apache Camel с клъстер Kubernetes

Един от проблемите на интеграцията днес е, че приложенията вече не са статични. В облачната инфраструктура работим с виртуални услуги, които се изпълняват едновременно на множество възли. Той дава възможност за архитектура на микроуслуги с мрежа от малки и леки услуги, които взаимодействат помежду си. Тези услуги имат ненадежден живот и ние трябва да ги откриваме динамично.

Поставянето на облачни услуги заедно е задача, която може да бъде решена с Apache Camel. Особено интересно е за вкуса на EIP и факта, че Camel има много адаптери и поддържа широка гама от протоколи. Последната версия 2.18 добавя компонента ServiceCall , който въвежда функция за извикване на API и разрешаване на адреса му чрез механизми за откриване на клъстер. В момента той поддържа консул, Kubernetes, Ribbon и др. Някои примерни кодове, където ServiceCall е конфигуриран с Consul, могат да бъдат намерени лесно. Тук ще използваме Kubernetes, защото това е любимото ми решение за клъстери.

Схемата за интеграция ще бъде следната:

Схема

Услугата Order и услугата Inventory ще бъдат няколко тривиални приложения Пролетно зареждане връщане на статични данни. Тук не сме обвързани с определен стек от технологии. Тези услуги произвеждат данните, които искаме да обработим.

Контролер за поръчка на услуги:

@RestController public class OrderController { private final OrderStorage orderStorage; @Autowired public OrderController(OrderStorage orderStorage) { this.orderStorage = orderStorage; } @RequestMapping('/info') public String info() { return 'Order Service UUID = ' + OrderApplication.serviceID; } @RequestMapping('/orders') public List getAll() { return orderStorage.getAll(); } @RequestMapping('/orders/{id}') public Order getOne(@PathVariable Integer id) { return orderStorage.getOne(id); } }

Произвежда данни във формат:

[{'id':1,'items':[2,3,4]},{'id':2,'items':[5,3]}]

Сервизният контролер Inventory е абсолютно подобна на услугата Order

@RestController public class InventoryController { private final InventoryStorage inventoryStorage; @Autowired public InventoryController(InventoryStorage inventoryStorage) { this.inventoryStorage = inventoryStorage; } @RequestMapping('/info') public String info() { return 'Inventory Service UUID = ' + InventoryApplication.serviceID; } @RequestMapping('/items') public List getAll() { return inventoryStorage.getAll(); } @RequestMapping('/items/{id}') public InventoryItem getOne(@PathVariable Integer id) { return inventoryStorage.getOne(id); } }

InventoryStorage това е общо хранилище, което съдържа данни. В този пример той връща статични предварително дефинирани обекти, които са класифицирани според следния формат.

[{'id':1,'name':'Laptop','description':'Up to 12-hours battery life','price':499.9},{'id':2,'name':'Monitor','description':'27-inch, response time: 7ms','price':200.0},{'id':3,'name':'Headphones','description':'Soft leather ear-cups','price':29.9},{'id':4,'name':'Mouse','description':'Designed for comfort and portability','price':19.0},{'id':5,'name':'Keyboard','description':'Layout: US','price':10.5}]

Ще напишем път на шлюз, който ги свързва, но без ServiceCall в тази стъпка:

rest('/orders') .get('/').description('Get all orders with details').outType(TestResponse.class) .route() .setHeader('Content-Type', constant('application/json')) .setHeader('Accept', constant('application/json')) .setHeader(Exchange.HTTP_METHOD, constant('GET')) .removeHeaders('CamelHttp*') .to('http4://localhost:8082/orders?bridgeEndpoint=true') .unmarshal(formatOrder) .enrich('direct:enrichFromInventory', new OrderAggregationStrategy()) .to('log:result') .endRest(); from('direct:enrichFromInventory') .transform().simple('${null}') .setHeader('Content-Type', constant('application/json')) .setHeader('Accept', constant('application/json')) .setHeader(Exchange.HTTP_METHOD, constant('GET')) .removeHeaders('CamelHttp*') .to('http4://localhost:8081/items?bridgeEndpoint=true') .unmarshal(formatInventory);

Сега си представете, че всяка услуга вече не е конкретен екземпляр, а облак от екземпляри, които функционират като един. Ще използваме Minikube, за да тестваме локално клъстера Kubernetes.

Конфигурирайте мрежовите пътища, за да видите локално възлите Kubernetes (даденият пример е за Mac / Linux среда):

каква е употребата на езика c
# remove existing routes sudo route -n delete 10/24 > /dev/null 2>&1 # add routes sudo route -n add 10.0.0.0/24 $(minikube ip) # 172.17.0.0/16 ip range is used by docker in minikube sudo route -n add 172.17.0.0/16 $(minikube ip) ifconfig 'bridge100' | grep member | awk '{print }’ # use interface name from the output of the previous command # needed for xhyve driver, which I'm using for testing sudo ifconfig bridge100 -hostfilter en5

Услуги за опаковане в Докер контейнери с конфигурация на Dockerfile като тази:

FROM openjdk:8-jdk-alpine VOLUME /tmp ADD target/order-srv-1.0-SNAPSHOT.jar app.jar ADD target/lib lib ENV JAVA_OPTS='' ENTRYPOINT exec java $JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -jar /app.jar

Създайте и изпратете изображенията на услугата в регистъра на Docker. Сега изпълнете възлите на локалния клъстер Kubernetes.

Конфигурация за внедряване на Kubernetes.yaml:

apiVersion: extensions/v1beta1 kind: Deployment metadata: name: inventory spec: replicas: 3 selector: matchLabels: app: inventory template: metadata: labels: app: inventory spec: containers: - name: inventory image: inventory-srv:latest imagePullPolicy: Never ports: - containerPort: 8081

Излагайте тези разполагания като клъстерни услуги:

kubectl expose deployment order-srv --type=NodePort kubectl expose deployment inventory-srv --type=NodePort

Сега можем да проверим дали заявките се обслужват от произволно избрани възли от клъстера. Изпълнение curl -X http://192.168.99.100:30517/info последователно няколко пъти за достъп до миникуба NodePort, за изложената услуга (използвайки вашия хост и порт). В резултат виждаме, че сме постигнали баланс на заявките. ~~~ Услуга за инвентаризация UUID = 22f8ca6b-f56b-4984-927b-cbf9fcf81da5 Услуга за инвентаризация UUID = b7a4d326-1e76-4051-a0a6-1016394fafda Услуга за инвентаризация UUID = b7a4d326-1e76-4051-a0a6UffaUDU-U0fafUU-U0fafUF-U0Faf UDUf-U0fafUF-U0Faf UDUF-U0Faf UDUF-U0Faf UFUF-U0UF UFUF UFUD Uf 4984-927b-cbf9fcf81da5 Услуга за инвентаризация UUID = 50323ddb-3ace-4424-820a-6b4e85775af4 ~~~

Добавете зависимостите camel-kubernetes и camel-netty4-http al pom.xml на проекта. След това конфигурирайте компонента ServiceCall да използва споделено откриване на главния възел Kubernetes за всички повиквания на услуги между дефинициите на маршрута:

KubernetesConfiguration kubernetesConfiguration = new KubernetesConfiguration(); kubernetesConfiguration.setMasterUrl('https://192.168.64.2:8443'); kubernetesConfiguration.setClientCertFile('/Users/antongoncharov/.minikube/client.crt'); kubernetesConfiguration.setClientKeyFile('/Users/antongoncharov/.minikube/client.key'); kubernetesConfiguration.setNamespace('default”); ServiceCallConfigurationDefinition config = new ServiceCallConfigurationDefinition(); config.setServiceDiscovery(new KubernetesClientServiceDiscovery(kubernetesConfiguration)); context.setServiceCallConfiguration(config);

ServiceCall EIP добре допълва Spring Boot. Повечето от опциите могат да бъдат зададени директно във файла application.properties

Подобрете маршрута на Camel с компонента ServiceCall:

rest('/orders') .get('/').description('Get all orders with details').outType(TestResponse.class) .route() .hystrix() .setHeader('Content-Type', constant('application/json')) .setHeader('Accept', constant('application/json')) .setHeader(Exchange.HTTP_METHOD, constant('GET')) .removeHeaders('CamelHttp*') .serviceCall('customer-srv','http4:customer-deployment?bridgeEndpoint=true') .unmarshal(formatOrder) .enrich('direct:enrichFromInventory', new OrderAggregationStrategy()) .to('log:result') .endRest(); from('direct:enrichFromInventory') .transform().simple('${null}') .setHeader('Content-Type', constant('application/json')) .setHeader('Accept', constant('application/json')) .setHeader(Exchange.HTTP_METHOD, constant('GET')) .removeHeaders('CamelHttp*') .serviceCall('order-srv','http4:order-srv?bridgeEndpoint=true') .unmarshal(formatInventory);

Също така активирахме прекъсвача по маршрута. Това е кука за интеграция, която позволява да се спрат отдалечените обаждания от системата, в случай на грешки при доставката или липса на наличност на получателя. Това е предназначено за предотвратяване на каскадни повреди в системата. Компонентът Hystrix помага да се постигне това чрез прилагане на схемата на прекъсвача.

Нека го стартираме и изпратим заявка за тест; ще получим общия отговор на двете услуги.

[{'id':1,'items':[{'id':2,'name':'Monitor','description':'27-inch, response time: 7ms','price':200.0},{'id':3,'name':'Headphones','description':'Soft leather ear-cups','price':29.9},{'id':4,'name':'Mouse','description':'Designed for comfort and portability','price':19.0}]},{'id':2,'items':[{'id':5,'name':'Keyboard','description':'Layout: US','price':10.5},{'id':3,'name':'Headphones','description':'Soft leather ear-cups','price':29.9}]}]

Резултатът е очакван.

Други случаи на употреба

Показах как Apache Camel може да интегрира микроуслуги в клъстер. Какви са другите приложения за тази рамка? Като цяло е полезно навсякъде, където базираното на правила маршрутизиране е решение. Например Apache Camel може да бъде a междинен софтуер за Интернет на нещата с адаптера Eclipse Kura. Той може да се справи с мониторинга чрез транспортиране на регистрационни сигнали от различни компоненти и услуги, както в системата CERN. Това може да бъде и интеграционна рамка за корпоративна SOA или портфолио за групова обработка на данни, въпреки че не се конкурира добре Apache Spark в тази област.

заключение

Виждате, че системната интеграция не е лесен процес. Имаме късмет, защото е натрупан много опит. Важно е да го прилагате правилно, за да създадете гъвкави и устойчиви на грешки решения.

За да се гарантира правилното приложение, препоръчвам да имате контролен списък с важни аспекти на интеграцията. Задължителните артикули включват:

  • Има ли отделен интеграционен слой?
  • Има ли тестове за интеграция?
  • Знаем ли максимално очакваната интензивност на данните?
  • Знаем ли очакваното време за доставка на данни?
  • Има ли значение корелацията на съобщенията? Какво се случва, ако една последователност е нарушена?
  • Трябва ли да го правим синхронно или асинхронно?
  • Къде най-често се променят правилата и форматите за маршрутизиране?
  • Имаме ли начини да наблюдаваме процеса?

В тази статия тествахме Apache Camel, a рамка лека система за интеграция, която помага да се спестят време и усилия при решаване на интеграционни проблеми. Както показахме, той може да служи като инструмент, който поддържа съответната архитектура на микроуслуги, като поема пълната отговорност за обмена на данни между микроуслуги.

Ако се интересувате да научите повече за Apache Camel, горещо препоръчвам книгата 'Camel in Action' от създателя на рамка , Клаус Ибсен. Официалната документация е достъпна на camel.apache.org .

Gulp Under the Hood: Изграждане на инструмент за автоматизация на задачи, базиран на поток

Back-End

Gulp Under the Hood: Изграждане на инструмент за автоматизация на задачи, базиран на поток
Старши инженер отзад, екип за извличане на фактури

Старши инженер отзад, екип за извличане на фактури

Други

Популярни Публикации
Плащане напред: Разбиране на изкупувания с ливъридж
Плащане напред: Разбиране на изкупувания с ливъридж
Индустриален анализ и Porter’s Five Force: По-задълбочен поглед върху силата на купувача
Индустриален анализ и Porter’s Five Force: По-задълбочен поглед върху силата на купувача
Разширена реалност vs. Виртуална реалност vs. Смесена реалност: Уводно ръководство
Разширена реалност vs. Виртуална реалност vs. Смесена реалност: Уводно ръководство
Ще отвори ли Spotify не-IPO пътя за технологичните компании?
Ще отвори ли Spotify не-IPO пътя за технологичните компании?
Прогнозиране на харесвания: Вътре в алгоритмите на прост механизъм за препоръки
Прогнозиране на харесвания: Вътре в алгоритмите на прост механизъм за препоръки
 
Ефективни стартови платки: какви са те и как да ги изградим
Ефективни стартови платки: какви са те и как да ги изградим
Ръководител на клиентския опит
Ръководител на клиентския опит
Игла в купа сено: чудесен урок за мащабен текстов алгоритъм за търсене
Игла в купа сено: чудесен урок за мащабен текстов алгоритъм за търсене
Структурата на данните Trie: Пренебрегван скъпоценен камък
Структурата на данните Trie: Пренебрегван скъпоценен камък
Краят на уеб формите
Краят на уеб формите
Популярни Публикации
  • какво е количествен фонд
  • уеб API в .net
  • при прилагане на принципа на проектиране на __________ свързаните елементи се групират заедно.
  • как да използвате материален дизайн на google
  • какво е powerpivot в excel
  • какъв език използва обработката
Категории
  • Инженерно Управление
  • Мобилен Дизайн
  • Разпределени Екипи
  • Пъргав
  • © 2022 | Всички Права Запазени

    portaldacalheta.pt