Микросервисы с JHipster (серия из 3 частей)
Первоначально опубликовано на deepu.tech .
Прошло довольно много времени с тех пор, как я писал блог, я писал несколько несколько лет назад, но никогда по-настоящему не продолжал писать. Поэтому, когда я решил снова начать писать, мне не пришлось много думать о теме, так как это было очень очевидно — JHipster .
JHipster – это платформа разработки веб-приложений Java и микросервисов. Если вы являетесь разработчиком JVM, вы, возможно, уже слышали о Хипстер . Если нет, что ж, вы многое упускаете, и я настоятельно рекомендую вам проверить это. Вы также можете ознакомиться с моей книгой ” Разработка полного стека с помощью JHipster ” на Amazon и Пакет чтобы узнать о хипстере.
Я работаю над JHipster с апреля 2015 года, и самая крутая функция, которую мне удалось реализовать до сих пор, – это, безусловно, создание нескольких приложений с использованием JDL. Эта функция доступна в последней версии Hipster. Если вы не знакомы с JDL, я рекомендую вам ознакомиться с документами по адресу Если вы не знакомы с JDL, я рекомендую вам ознакомиться с документами по адресу
Приложение для электронной коммерции
Итак, давайте посмотрим, как мы можем создать стек микросервисов с помощью JHipster. Сегодня мы построим магазин электронной коммерции. Стек включает в себя-
Обнаружение службы с помощью Реестра JHipster , приложение для загрузки Spring, которое упаковывает сервер Eureka и сервер конфигурации Spring cloud.
Управление API и шлюз с использованием Spring Boot, Netflix Zuul, ReactJS и Swagger.
Микросервисы, использующие пружинную загрузку.
Мониторинг с помощью Консоли JHipster , которая изготовлена из эластичного стека (ELK) и Зипкина.
Архитектура приложений микросервисов
Шлюз направляет входящие запросы двум микросервисам, приложению выставления счетов и приложению уведомлений.
Требования
Чтобы следовать этому руководству, вам понадобится последняя версия Docker , Докер-составить , Узлы и Java установлен на вашем компьютере. Ниже приведены версии, которые я установил ( Обновление : С JHipster 6+ вы можете использовать Java 11 и 12).
$ docker -v Docker version 18.06.1-ce, build e68fc7a $ docker-compose -v docker-compose version 1.20.1, build 5d8c71b $ node -v v8.11.4 $ java -version openjdk version "1.8.0_212" OpenJDK Runtime Environment (Zulu 8.38.0.13-CA-linux64) (build 1.8.0_212-b04) OpenJDK 64-Bit Server VM (Zulu 8.38.0.13-CA-linux64) (build 25.212-b04, mixed mode)
Во-первых, установите последнюю версию Hipster
$ npm install generator-jhipster -g
Убедитесь, что у вас есть версия 5.3.4 или выше, запустив
$ jhipster --version
Создание ЛЗЕ
Теперь давайте создадим нашу ЛЗЕ. Перейдите в JDLStudio или ваш любимый IDE/редактор ( Вы можете использовать Hipster IDE плагин если вам нравится ).
Во-первых, давайте определимся с нашими приложениями. Мы начнем со Шлюза
application {
config {
baseName store,
applicationType gateway,
packageName com.jhipster.demo.store,
serviceDiscoveryType eureka,
authenticationType jwt,
prodDatabaseType mysql,
cacheProvider hazelcast,
buildTool gradle,
clientFramework react,
testFrameworks [protractor]
}
entities *
}
Большинство опций не требуют пояснений, мы создаем приложение с именем Store типа Шлюз с JWT аутентификацией и обнаружением услуг на основе Эврики . Приложение использует MySQL базу данных и Hazelcast для кэша. Он построен с использованием Грейдл . Для клиентской стороны он использует Реагировать и Дерзость . Он также имеет Транспортир для сквозного тестирования.
В конце определения вы можете увидеть сущности * , мы вернемся к этому позже.
Теперь давайте определим наш микросервис счетов-фактур
application {
config {
baseName invoice,
applicationType microservice,
packageName com.jhipster.demo.invoice,
serviceDiscoveryType eureka,
authenticationType jwt,
prodDatabaseType mysql,
buildTool gradle,
serverPort 8081
}
entities Invoice, Shipment
}
Он следует аналогичным параметрам, таким как наш шлюз, и, поскольку он является микросервисом, он не определяет никаких параметров на стороне клиента, а также пропускает управление пользователями, поскольку оно будет обрабатываться шлюзом. Кроме того, мы также упомянули пользовательский порт 8081 поскольку мы не хотим, чтобы это приложение конфликтовало с портом 8080 по умолчанию, используемым Шлюзом.
Теперь давайте определим второй микросервис, приложение для уведомления
application {
config {
baseName notification,
applicationType microservice,
packageName com.jhipster.demo.notification,
serviceDiscoveryType eureka,
authenticationType jwt,
databaseType mongodb,
cacheProvider no,
enableHibernateCache false,
buildTool gradle,
serverPort 8082
}
entities Notification
}
Это приложение следует многим параметрам, аналогичным приложению шлюза и счета, но вместо использования MySQL оно использует MongoDB как свою базу данных, а также отключает кэш.
Теперь, когда наши определения приложений закончены, мы перейдем к определению нашей модели сущностей.
Для нашего приложения магазина шлюза давайте определим следующие сущности и перечисления
/** Product sold by the Online store */
entity Product {
name String required
description String
price BigDecimal required min(0)
size Size required
image ImageBlob
}
enum Size {
S, M, L, XL, XXL
}
entity ProductCategory {
name String required
description String
}
entity Customer {
firstName String required
lastName String required
gender Gender required
email String required pattern(/^[^@\s]+@[^@\s]+\.[^@\s]+$/)
phone String required
addressLine1 String required
addressLine2 String
city String required
country String required
}
enum Gender {
MALE, FEMALE, OTHER
}
entity ProductOrder {
placedDate Instant required
status OrderStatus required
code String required
invoiceId Long
}
enum OrderStatus {
COMPLETED, PENDING, CANCELLED
}
entity OrderItem {
quantity Integer required min(0)
totalPrice BigDecimal required min(0)
status OrderItemStatus required
}
enum OrderItemStatus {
AVAILABLE, OUT_OF_STOCK, BACK_ORDER
}
relationship OneToOne {
Customer{user(login) required} to User
}
relationship ManyToOne {
OrderItem{product(name) required} to Product
}
relationship OneToMany {
Customer{order} to ProductOrder{customer(email) required},
ProductOrder{orderItem} to OrderItem{order(code) required},
ProductCategory{product} to Product{productCategory(name)}
}
service Product, ProductCategory, Customer, ProductOrder, OrderItem with serviceClass
paginate Product, Customer, ProductOrder, OrderItem with pagination
JDL определяет сущности, перечисления, отношения между сущностями и параметры, такие как разбивка на страницы и уровень обслуживания.
Определение поля сущности следует синтаксису
entity{ [ *] }
Определение отношения следует синтаксису
relationship (OneToMany | ManyToOne | OneToOne | ManyToMany) {
[{[()]}]
to
[{[()]}]
}
Обратитесь к JDL docs для получения полной справки по DSL.
Приложение микросервиса счетов-фактур содержит следующие объекты
entity Invoice {
code String required
date Instant required
details String
status InvoiceStatus required
paymentMethod PaymentMethod required
paymentDate Instant required
paymentAmount BigDecimal required
}
enum InvoiceStatus {
PAID, ISSUED, CANCELLED
}
entity Shipment {
trackingCode String
date Instant required
details String
}
enum PaymentMethod {
CREDIT_CARD, CASH_ON_DELIVERY, PAYPAL
}
relationship OneToMany {
Invoice{shipment} to Shipment{invoice(code) required}
}
service Invoice, Shipment with serviceClass
paginate Invoice, Shipment with pagination
microservice Invoice, Shipment with invoice
Обратите внимание на последнюю микросервисную опцию, объявленную здесь, она указывает, что эти объекты принадлежат микросервису с именем счет-фактура чтобы наш шлюз знал, куда направлять запросы для этих объектов.
Теперь давайте посмотрим сущности для приложения микросервиса уведомлений
entity Notification {
date Instant required
details String
sentDate Instant required
format NotificationType required
userId Long required
productId Long required
}
enum NotificationType {
EMAIL, SMS, PARCEL
}
microservice Notification with notification
Теперь давайте вернемся к ключевому слову entities, которое мы использовали в определениях наших приложений.
application {
config {
...
}
entities *
}
application {
config {
...
}
entities Invoice, Shipment
}
application {
config {
...
}
entities Notification
}
/* Entities for Store Gateway */
entity Product {
...
}
entity ProductCategory {
...
}
entity Customer {
...
}
entity ProductOrder {
...
}
entity OrderItem {
...
}
microservice Invoice, Shipment with invoice
/* Entities for Invoice microservice */
entity Invoice {
...
}
entity Shipment {
...
}
/* Entities for notification microservice */
entity Notification {
...
}
microservice Notification with notification
Здесь мы инструктируем приложение шлюза хранилища, что оно должно содержать все сущности, определенные в JDL, и шлюз будет знать, что нужно пропускать код на стороне сервера для сущностей, принадлежащих другому микросервису, и, следовательно, будет генерировать только код на стороне клиента для тех, здесь, а именно Счет-фактура , Отгрузка , и Уведомление . Мы также инструктируем приложение для выставления счетов и приложение для уведомлений включать в себя его сущности.
Создание приложений
Создайте папку, в которой мы хотим создать наш стек микросервисов.
$ mkdir ecommerce && cd ecommerce
Теперь давайте соберем все вместе в файл JDL. Давайте назовем его app.jdl и сохраним в эту папку.
application {
config {
baseName store,
applicationType gateway,
packageName com.jhipster.demo.store,
serviceDiscoveryType eureka,
authenticationType jwt,
prodDatabaseType mysql,
cacheProvider hazelcast,
buildTool gradle,
clientFramework react,
testFrameworks [protractor]
}
entities *
}
application {
config {
baseName invoice,
applicationType microservice,
packageName com.jhipster.demo.invoice,
serviceDiscoveryType eureka,
authenticationType jwt,
prodDatabaseType mysql,
buildTool gradle,
serverPort 8081
}
entities Invoice, Shipment
}
application {
config {
baseName notification,
applicationType microservice,
packageName com.jhipster.demo.notification,
serviceDiscoveryType eureka,
authenticationType jwt,
databaseType mongodb,
cacheProvider no,
enableHibernateCache false,
buildTool gradle,
serverPort 8082
}
entities Notification
}
/* Entities for Store Gateway */
/** Product sold by the Online store */
entity Product {
name String required
description String
price BigDecimal required min(0)
size Size required
image ImageBlob
}
enum Size {
S, M, L, XL, XXL
}
entity ProductCategory {
name String required
description String
}
entity Customer {
firstName String required
lastName String required
gender Gender required
email String required pattern(/^[^@\s]+@[^@\s]+\.[^@\s]+$/)
phone String required
addressLine1 String required
addressLine2 String
city String required
country String required
}
enum Gender {
MALE, FEMALE, OTHER
}
entity ProductOrder {
placedDate Instant required
status OrderStatus required
code String required
invoiceId Long
}
enum OrderStatus {
COMPLETED, PENDING, CANCELLED
}
entity OrderItem {
quantity Integer required min(0)
totalPrice BigDecimal required min(0)
status OrderItemStatus required
}
enum OrderItemStatus {
AVAILABLE, OUT_OF_STOCK, BACK_ORDER
}
relationship OneToOne {
Customer{user(login) required} to User
}
relationship ManyToOne {
OrderItem{product(name) required} to Product
}
relationship OneToMany {
Customer{order} to ProductOrder{customer(email) required},
ProductOrder{orderItem} to OrderItem{order(code) required} ,
ProductCategory{product} to Product{productCategory(name)}
}
service Product, ProductCategory, Customer, ProductOrder, OrderItem with serviceClass
paginate Product, Customer, ProductOrder, OrderItem with pagination
/* Entities for Invoice microservice */
entity Invoice {
code String required
date Instant required
details String
status InvoiceStatus required
paymentMethod PaymentMethod required
paymentDate Instant required
paymentAmount BigDecimal required
}
enum InvoiceStatus {
PAID, ISSUED, CANCELLED
}
entity Shipment {
trackingCode String
date Instant required
details String
}
enum PaymentMethod {
CREDIT_CARD, CASH_ON_DELIVERY, PAYPAL
}
relationship OneToMany {
Invoice{shipment} to Shipment{invoice(code) required}
}
service Invoice, Shipment with serviceClass
paginate Invoice, Shipment with pagination
microservice Invoice, Shipment with invoice
/* Entities for notification microservice */
entity Notification {
date Instant required
details String
sentDate Instant required
format NotificationType required
userId Long required
productId Long required
}
enum NotificationType {
EMAIL, SMS, PARCEL
}
microservice Notification with notification
Теперь давайте вызовем интерфейс командной строки Hipster для импорта этого файла
$ jhipster import-jdl app.jdl
Это создаст магазин , счет-фактуру и уведомления папки и будет делать следующее в каждой из папок
Создайте соответствующую конфигурацию приложения и сущностей.
Создайте исходный код приложения и сущностей на основе конфигураций.
Установите зависимости NPM для приложения.
Как только процесс будет завершен, вы должны увидеть следующее на своей консоли
Entity Product generated successfully. Entity ProductCategory generated successfully. Entity Customer generated successfully. Entity ProductOrder generated successfully. Entity OrderItem generated successfully. Entity Invoice generated successfully. Entity Shipment generated successfully. Entity Notification generated successfully. Congratulations, JHipster execution is complete!
Пройдитесь по сгенерированному коду, чтобы ознакомиться с ним.
Запуск приложений с помощью Docker
Теперь, когда наши приложения созданы, пришло время протестировать их локально с помощью Docker. Для этого сначала сгенерируем некоторые конфигурации docker compose с помощью JHipster.
Создайте новую папку внутри папки электронная коммерция и выполните команду JHipster docker-compose
$ mkdir docker-compose && cd docker-compose $ jhipster docker-compose
Он предложит вам задать несколько вопросов, выберите ответы, как показано ниже
🐳 Welcome to the JHipster Docker Compose Sub-Generator 🐳 Files will be generated in folder: /home/deepu/workspace/temp/ecommerce/docker-compose ✔ Docker is installed ? Which *type* of application would you like to deploy? Microservice application ? Which *type* of gateway would you like to use? JHipster gateway based on Netflix Zuul ? Enter the root directory where your gateway(s) and microservices are located ../ 3 applications found at /home/deepu/workspace/temp/ecommerce/ ? Which applications do you want to include in your configuration? invoice, notification, store ? Which applications do you want to use with clustered databases (only available with MongoDB and Couchbase)? ? Do you want to setup monitoring for your applications ? Yes, for logs and metrics with the JHipster Console (based on ELK and Zipkin) ? You have selected the JHipster Console which is based on the ELK stack and additional technologies, which one do you want to use ? Zipkin, for distributed tracing (only compatible with JHipster >= v4.2.0) JHipster registry detected as the service discovery and configuration provider used by your apps ? Enter the admin password used to secure the JHipster Registry? admin
Это приведет к созданию всех необходимых конфигураций компоновки докеров для стека, а также к распечатке дальнейших инструкций по созданию образов докеров.
Примечание: В последних версиях для хипстеров мы перешли на использование Кливер для создания изображений докеров. Это огромное улучшение по сравнению с плагином Docker Maven, который мы использовали, в результате команда для создания изображения изменилась на ./gradlew - Ппрод война ботинок Джибдокербилд .
Docker Compose configuration generated with missing images! To generate the missing Docker image(s), please run: ./gradlew -Pprod bootWar jibDockerBuild in /home/deepu/workspace/temp/ecommerce/invoice ./gradlew -Pprod bootWar jibDockerBuild in /home/deepu/workspace/temp/ecommerce/notification ./gradlew -Pprod bootWar jibDockerBuild in /home/deepu/workspace/temp/ecommerce/store
Следуйте инструкциям и создайте образы docker. Как только все 3 изображения будут созданы, выполните приведенную ниже команду из папки docker-compose , чтобы запустить все.
$ docker-compose up -d
Как только контейнеры запустятся, вы можете передавать журналы в потоковом режиме, используя команду ниже
$ docker-compose logs -f
Теперь наведите свой любимый браузер на http://localhost:8080/ и увидеть приложение микросервиса электронной коммерции в действии.
Приложение шлюза (магазин)
Вы можете увидеть реестр JHipster в действии по адресу http://localhost:8761/
Реестр хипстеров
И, наконец, консоль для хипстеров в http://localhost:5601 /
Консоль JHipster- панель управления Kibana
Как только вы закончите играть, вы можете отключить все, выполнив приведенную ниже команду в папке docker-compose
docker-compose down
Надеюсь, вам понравилось создавать микросервисы с помощью JHipster. Чтобы узнать, как преобразовать монолит JHipster в микросервисы, ознакомьтесь с моей книгой ” Разработка полного стека с помощью JHipster ” на Amazon и Пакт .
В ближайшие недели я напишу несколько постов о развертывании этого стека микросервисов для различных облачных провайдеров, таких как GCP, Azure, AWS, Heroku и так далее.
Если вам нравится хипстер, не забудьте поставить ему звездочку Github .
Если вам понравилась эта статья, пожалуйста, оставьте лайк или комментарий.
Вы можете следовать за мной дальше Twitter и LinkedIn .
Мои другие связанные посты:
Развертывание микросервисов JHipster в службе Azure Kubernetes (AKS)
Микросервисы JHipster с сервисной сеткой Istio на Kubernetes
Первоначально опубликовано в Medium 22 сентября 2018 г.
Микросервисы с JHipster (серия из 3 частей)
Оригинал: “https://dev.to/deepu105/create-full-microservice-stack-using-jhipster-domain-language-under-30-minutes-4ele”