Русский
Русский
English
Статистика
Реклама

Software development

Перевод Зависимости JavaScript Все, что вы когда-либо хотели знать, но боялись спросить

02.03.2021 16:05:07 | Автор: admin

Ваше подробное руководство по пяти типам зависимости

Привет, хабровчане. Для будущих учащихся на курсе "JavaScript Developer. Professional" подготовили перевод материала.

Также приглашаем всех желающих на открытый вебинар по теме
Vue 3 возможности новой версии одного из самых популярных фронтенд фреймворков. На занятии участники вместе с экспертом:
рассмотрят ключевые отличия в синтаксисе vue2 от vue3;
разберут, как работать с vue-router и VueX в новой версии фреймворка;
cоздадут проект на Vue 3 с нуля с помощью Vue-cli.


Независимо от того, являетесь ли Вы back-end разработчиком, работающим с Node.js, или front-end разработчиком, использующим Node.js только в качестве инструмента для пакетирования и комплектации, Вы наверняка наткнулись на систему зависимостей.

Но почему их 5 типов (да, это не опечатка, есть 5 типов зависимостей), и для какого случая они используются? На эти вопросы мы ответим сегодня, так что сядьте поудобнее и расслабьтесь, потому что это будет интересно.

. . .

Normal (runtime) dependencies (cтандартные (во время выполнения программы) зависимости)

Давайте начнем с простого, хорошо?

Стандартные зависимости это те, которые вы видите в списке "dependencies" в вашем файле package.json. В большинстве случаев они указывают только имя (для своего ключа) и версию (значение), а затем NPM (node package manager или любой другой менеджер пакетов) позаботится об их захвате из глобального регистра (на npmjs.org).

Однако, это еще не все. Вместо точного номера версии вашей зависимости вы можете указать:

  • Примерный вариант. Вы можете работать с обычными числовыми операторами сравнения, указывая версии больше одного определенного числа (т.е. >1.2.0 ), любой версии ниже или равной другому числу (т.е. <=1.2.0 ), а также можете обыгрывать любую из их комбинаций (т.е. >= , > , <) . Вы также можете указать эквивалентную версию с помощью оператора ~ перед номером версии (т.е. "lodash":"~1.2.2, который загрузит что угодно между 1.2.2 и 1.3.0 или, другими словами, только патчи). И мы также можем указать "совместимую" версию с другим номером, который использует semver для понимания совместимости (т.е. "lodash": "^1.2.0", которая не загрузит ничего, из того что включает в себя изменение с нарушением или отсутствием каких-либо функций).

  • URL-АДРЕС. Правильно, вы даже можете обойтись без версии и напрямую ссылаться на определенный URL, по сути загрузив этот модуль откуда-нибудь еще (например, с Github или напрямую скачав tarball-файл).

  • Локальный файл. Да, вы даже можете непосредственно обращаться к одному из ваших локальных файлов. Это очень удобно, если вы разрабатываете модуль и хотите протестировать его на проекте, прежде чем выпускать его на NPM. С помощью опции "Локальный файл" вы можете сделать ссылку на папку вашего локального модуля. Вы можете использовать как полный, так и частичный пути, при условии, что вы используете префикс-функцию с помощью file:// .

Когда ты будешь использовать стандартные зависимости?

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

Это может показаться простым, но если, например, ваш проект на самом деле является модулем, то вам нужно более внимательно разобраться в том, что это значит. Если ваш модуль предназначен для использования с другими проектами, такими как React или Babel, ваши зависимости не должны включать их, так как они, как предполагается, уже присутствуют, тем не менее, они все равно нужны (мы это увидим позже, где они появятся через секунду).

Так что, помните, если это абсолютно необходимо для работы вашего проекта, и вы не можете рассчитывать на то, что другая библиотека включит их, то они должны быть включены в ваш список зависимостей.

. . .

Peer dependencies (Равные зависимости)

Peer dependencies это особый вид зависимостей, в том смысле, что они предназначены для указания тех пакетов, которые требуются вашему проекту, или, вернее, с которыми он совместим. Тем не менее, вы можете не запрашивать их конкретно в своем коде.

Подождите, зависимость, которая вам не требуется? Я знаю, это звучит странно, но подумайте о плагине Babel, он нуждается в Babel в том смысле, что если его там нет, то он не сможет работать, однако, он может и не требовать Babel явно для чего-либо.

Теперь, потенциально, вы можете добавить Babel в список стандартных зависимостей, однако, при установке плагина, он также попытается установить Babel. И если вы используете, например, NPM, он установит его как локальную зависимость вашего плагина, что означает он будет дублировать уже существующую установленную Babel для хост-проекта, находящегося в папке плагина.

Когда ты будешь использовать Peer dependencies?

Вы можете прочитать больше о Peer dependencies здесь, однако, поймите, что вы будете использовать их только тогда, когда нужно указать на недостаточно прочную связь с другим проектом.

Другими словами:

  • Когда она вам нужна, но нет необходимости употреблять ее сразу и однозначно. Тогда это peer dependency.

  • Когда она вам нужна, но она уже должна быть установлена другим проектом. Тогда это peer dependency.

Примерами того, когда вы хотите использовать peerDependencies, являются:

  • Babel плагины. Ты хочешь декларировать такие же вещи, как и сам Babel, в качестве равной зависимости (peer dependency).

  • Express middleware packages (Экспресс-пакеты для промежуточной обработки): Это всего лишь один пример модуля NPM, который требует использования peer dependencies. Вы хотите определить приложение Express как зависимость, но не жесткую, в противном случае каждое промежуточное ПО (middleware) будет каждый раз инсталлировать всю структуру заново.

  • Если вы собираете Micro Frontend (Микрофронтенд), пытаясь решить, какие зависимости являются внешними (чтобы они не были связаны), а какие нет. Peer dependencies могут быть хорошим решением для этого.

  • Bit components. Если вы создаете и публикуете front-end компоненты, например, когда вы совместно используете React-компоненты на Bit (Github), вам нужно назначить react библиотеку как peer dependency. Это позволит удостовериться, что нужная библиотека доступна в хостинговом проекте без установки ее в качестве прямой зависимости от него.

Например, взгляните на этот React компонент, который я опубликовал некоторое время назад: это простая кнопка, которую можно выбрать (вы нажимаете на нее и она остается выбранной до тех пор, пока не будет нажата снова).

Снимок экрана component, как видно на Bits component hub.

Если вы установите его, вы получите полный код, который содержит файл package.json, в котором перечислены все peer dependencies:

Обратите внимание, что пакет не имеет прямой зависимости, несмотря на то, что для работы ему необходима React-библиотека.

Это также помогает сохранить размер нашего компонента как можно меньше (1KB) ничего лишнего не добавляется.

. . .

Dev Dependencies (Dev зависимости)

Имя говорит обо всем, не так ли? Я имею в виду, что так и должно быть, но когда имена действительно помогают нам, разработчикам, в нашей повседневной работе? Я точно знаю.

Зависимости процесса разработки (Development dependencies) предназначены для того, чтобы содержать только те модули, которые вы используете на этапе разработки вашего проекта.

Да, но есть и другие, например, инструменты для подшивки (linting tools), документация и тому подобное.

Дело в том, что если вы можете запустить проект без использования этого набора инструментов, тогда это dev dependency.

Принцип их работы заключается в том, что зависимости разработки устанавливаются только при запуске npm install или npm link из корневой папки вашего проекта.

Подумайте об этом, в этом случае имеет смысл установить их, так как вы разрабатываете свой собственный проект. Но если вы устанавливаете свой проект внутри другого, то этот процесс будет игнорировать ваши dev dependencies.

Когда ты будешь использовать dev dependencies?

Любая зависимость, которая не требуется для производственного процесса, скорее всего, будет считаться dev dependencies (зависимости развития).

Дело в том, что это отлично работает для всех модулей, кроме вашего хост-проекта.

Все установленные внутри хост-проекта зависимости будут пропускать dev-зависимости модулей во время инсталляции, но всякий раз, когда вы повторно запускаете npm install в хост-проекте, он будет устанавливать заново все пропущенные ранее dev-зависимости модулей.

Поэтому рассмотрим использование Dev зависимостей только для пакетов и модулей, которые будут использоваться другими проектами.

. . .

Связанные зависимости (Bundled Dependencies)

Они предназначены для тех случаев, когда вы упаковываете свой проект в один файл. Это делается с помощью команды npm pack, которая превращает вашу папку в тарбол (tarball-файл).

Теперь, если вы сделаете это и добавите имена некоторых из ваших зависимостей в массив под названием bundledDependencies (забавный факт: если вы используете bundleDependencies, это тоже будет работать), то тарбол также будет содержать эти зависимости внутри этого массива.

{...   "dependencies": {    "lodash": "1.0.2",    "request": "4.0.1"  },  "bundledDependencies": ["lodash"]...}

Посмотрите на эту часть файла package.json, с такой установкой, при запуске команды npm pack вы получите файл tarball, также содержащий пакет lodash внутри.

Это очень удобно при распространении ваших пакетов в однофайловом формате (помните, что вы также можете указать их URL или локальный путь как стандартную зависимость).

. . .

Дополнительные зависимости (Optional dependencies)

Наконец, этот тип зависимостей такой же, как и обычные, они ведут себя и могут быть настроены точно таким же образом. Единственная разница? NPM не выйдет с ошибкой, в случае, если не сможет установить их.

Обычно, когда вы запускаете npm install и процесс не может установить обычную зависимость по какой-либо причине (будь то из-за сбоя в сети, не может найти файл, версию или что-нибудь ещё), то он выдаст ошибку и отменит процесс установки.

Дополнительные зависимости вместо этого позволят NPM продолжать работу. Конечно, вы отвечаете за написание кода, который способен справиться с этими отсутствующими зависимостями, например:

let foo = null;try {  foo = require("foo-dep");} catch (e) {  foo = require("./local-polyfill")}//... use foo from here on out

Когда вы будете использовать дополнительные зависимости (optional dependencies)?

Очевидный пример использования этого типа зависимостей когда вы используете ненадежный источник. Я спрашиваю, зачем это делать? Хороший вопрос. Понятия не имею, но вы определенно можете это сделать, единственная проблема в том, что вам нужно убедиться, что ваш код может с этим справиться, если отсутствуют зависимости.

Но другой интересный вариант использования, это установка действительно необязательных зависимостей (optional dependencies). Я имею в виду, что иногда у вас могут быть специфические для системы зависимости, для таких вещей, как совместимость с CI(Continuous Integration)-платформой. В таких сценариях, когда используете платформу, вы захотите установить эти зависимости, в другом случае, проигнорируете.

Для таких ситуаций можно использовать обычную npm install, когда вы используете полный набор зависимостей, а затем использовать npm install --no-optional, когда вы хотите избежать их. Таким образом, вы пропустите эти опции и сосредоточитесь только на обязательных зависимостях.

. . .

Каждый, кто когда-либо пользовался NPM в тот или иной момент, слышал о стандартных и dev-зависимостях. Остальные 3, однако, можно считать менее популярными собратьями.

Хотя некоторые из них действительно сосредоточены на очень специфических сценариях, они могут быть очень удобны, когда с ними сталкиваешься.

Знали ли вы, что у вас так много вариантов? Оставьте комментарий ниже, если вы использовали некоторые из менее распространенных и расскажите нам, как вы их использовали!


Узнать подробнее о курсе "JavaScript Developer. Professional".

Смотреть открытый вебинар по теме Vue 3 возможности новой версии одного из самых популярных фронтенд фреймворков.

Подробнее..

Перевод Изучение методов кэширования в React

04.03.2021 20:15:20 | Автор: admin

Как использовать memoization, contexts, useMemo, useState, и useEffect

Для будущих учащихся на курсе "React.js Developer" подготовили перевод материала. Также приглашаем всех желающих на открытый вебинар ReactJS: быстрый старт. Сильные и слабые стороны.


То, что мы создадим сегодня! Фотография - автора статьиТо, что мы создадим сегодня! Фотография - автора статьи

Сбор данных в React это одно. Хранение и кэширование этих данных это другая история. Возможности кажутся бесконечными, а различия часто тонкие, что делает выбор правильной техники иногда немного сложным.

Сегодня мы исследуем различные методики и рассмотрим все их детали и тонкости. Следует ли использовать useMemo или memoization? Должен ли я хранить данные с помощью useState и context? Когда мы закончим, вы должны быть в состоянии сделать осознанный выбор в отношении кэширования данных. Вы узнаете обо всех тонкостях.

И много анимированных GIF-файлов. Что еще вы можете желать?

Давайте начнем!

Наши данные

Перед тем, как нам углубиться в код, мы можем бегло взглянуть на данные, которые будем извлекать из (большинства) наших компонентов. Файл, который действует как наш API, выглядит следующим образом:

export default function handler(req, res) {  setTimeout(    () =>      res.status(200).json({        randomNumber: Math.round(Math.random() * 10000),        people: [          { name: "John Doe" },          { name: "Olive Yew" },          { name: "Allie Grater" },        ],      }),    750  );}

Этот код выполняется, когда мы делаем запрос к пути /api/people в нашем проекте. Как видите, мы вернули объект с двумя свойствами:

  • randomNumber: случайное число в диапазоне 0-10000.

  • people: статический массив с тремя вымышленными именами.

Свойство randomNumber поможет нам визуализировать, отображаем ли мы кэшированные данные во фронтенде или нет. Просто продолжайте читать. Скоро это будет понятно.

Обратите внимание, что мы симулируем небольшую задержку сети с помощью setTimeout.

Компонент People

Когда мы отображаем данные из нашего API, мы передаем их компоненту под названием PeopleRenderer. Это выглядит так:

Учитывая все вышесказанное, давайте посмотрим на первое решение ниже.

. . .

useEffect

Внутри наших компонентов мы могли бы использовать хук-эффект useEffect Hook для получения данных. Затем мы можем хранить их локально (внутри компонента), используя useState :

import { useEffect, useState } from "react";import PeopleRenderer from "../PeopleRenderer";export default function PeopleUseEffect() {  const [json, setJson] = useState(null);  useEffect(() => {    fetch("/api/people")      .then((response) => response.json())      .then((data) => setJson(data));  }, []);  return <PeopleRenderer json={json} />;}

При передаче пустого массива в качестве второго параметра (см. строку 11), useEffect Hook (хук-эффект) будет выполнен, когда наш компонент будет установлен в DOM (Document Object Model) и только после этого. Он не будет выполняться снова, когда наш компонент будет перезагружен. Это называется "выполнить один раз" Hook (хук).

Ограничение использования useEffect в этом случае заключается в том, что когда мы имеем несколько экземпляров компонента в нашем DOM, все они будут получать данные по отдельности (когда они установлены):

В этом способе нет ничего плохого. Иногда, это именно то, что мы хотим. Но в других случаях нам может понадобиться один раз получить данные и повторно использовать их во всех других случаях путем кэширования. Мы можем использовать несколько способов для достижения этого.

. . .

Memoization (Мемоизация)

Memoization это причудливое слово для очень простой техники. Это означает, что вы создаете функцию, и каждый раз, когда она вызывается заново, она сохраняет результаты выполнения в кэше для предотвращения повторных вычислений.

При первом вызове этой memoized функции результаты рассчитываются (или извлекаются, что бы Вы ни делали внутри тела функции). Перед возвращением результатов вы храните их в кэше под ключом, который создается с входными параметрами:

const MyMemoizedFunction = (age) => {  if(cache.hasKey(age)) {    return cache.get(age);  }  const value = `You are ${age} years old!`;  cache.set(age, value);  return value;}

Создание такого кода шаблона может быстро стать громоздким, поэтому такие популярные библиотеки, как Lodash и Underscore, предоставляют утилиты, которые можно использовать для легкого создания memoized функций:

import memoize from "lodash.memoize";const MyFunction = (age) => {  return `You are ${age} years old!`;}const MyMemoizedFunction = memoize(MyFunction);

Использование memoization для получения данных

Мы можем использовать эту технологию при получении данных. Создаем функцию getData, которая возвращает Promise, доступный по окончании запроса на получение данных. Мемоизуем (memoize) объект Promise:

import memoize from "lodash.memoize";const getData = () =>  new Promise((resolve) => {    fetch("http://localhost:3000/api/people")      .then((response) => response.json())      .then((data) => resolve(data));  });export default memoize(getData);

Обратите внимание, что в этом примере мы не работали с ошибками. Это заслуживает отдельной статьи, особенно когда мы используем мемоизацию (memoization) (также будет мемоизован (memoized) отклонённый Promise , что может быть проблематично).

Теперь мы можем заменить нашuseEffect Hook на другой, который выглядит так:

import { useEffect, useState } from "react";import getData from "./getData";import PeopleRenderer from "../PeopleRenderer";export default function PeopleMemoize() {  const [json, setJson] = useState(null);  useEffect(() => {    getData().then((data) => setJson(data));  }, []);  return <PeopleRenderer json={json} />;}

Так как результат getData мемоизуется (memoized), все наши компоненты получат одни и те же данные, когда они будут смонтированы:

Анимация: В наших компонентах используется один и тот же memoized Promise.Анимация: В наших компонентах используется один и тот же memoized Promise.

Стоит также отметить, что данные уже предварительно собраны, когда мы открываем страницу memoize.tsx (перед тем, как мы смонтируем первую версию нашего компонента). Это потому, что мы определили нашу функцию getData в отдельном файле, который включен в верхнюю часть нашей страницы, и Promise создается при загрузке этого файла.

Мы также можем аннулировать, признать недействительным (пустым) кэш, назначив совершенно новый Cache в качестве свойства cache нашей мемоизованной (memoized) функции:

getData.cache = new memoize.Cache();

Как вариант, вы можете очистить существующий кэш (с помощью функции Map):

getData.cache.clear();

Но это специфичная функциональность для Lodash. Другие библиотеки требуют иных решений. Здесь вы видите аннулирование кэша в действии на примере:

Анимация: Сброс кэша memoized функции getData.Анимация: Сброс кэша memoized функции getData.

. . .

React Context (React Контекст)

Еще одним популярным и широко обсуждаемым (но часто непонятным) инструментом является React Context. И на заметку, еще раз, он не заменяет такие инструменты, как Redux. Это не инструмент управления состоянием.

Mark Erikson ведет тяжелую битву в Интернете и продолжает объяснять, почему это так. Настоятельно рекомендую прочитать его последнюю статью на эту тему.

И если вам это действительно интересно, прочитайте и мою статью по этой теме:

Так что же такое Context (Контекст)? Это механизм для внесения данных в ваше дерево компонентов. Если у вас есть какие-то данные, вы можете хранить их, например, с помощью useState Hook внутри компонента высоко в иерархии компонентов. Затем вы можете с помощью Context Provider внедрить данные в дерево, после чего вы сможете читать (использовать) данные в любом из компонентов внизу.

Это легче понять на примере. Во-первых, создайте новый контекст:

import { createContext } from "react";export const PeopleContext = createContext(null);

Затем мы заворачиваем (wrap) тот компонент, который отображает (renders) ваши компоненты People, с помощью Context Provider:

export default function Context() {  const [json, setJson] = useState(null);  useEffect(() => {    fetch("/api/people")      .then((response) => response.json())      .then((data) => setJson(data));  }, []);  return (    <PeopleContext.Provider value={{ json }}>        ...    </PeopleContext.Provider>  );}

На 12-ой строке мы можем сделать все, что захотим. В какой-то момент, далее вниз по дереву, мы отобразим наш компонент (компоненты) People:

import { useContext } from "react";import PeopleRenderer from "../PeopleRenderer";import { PeopleContext } from "./context";export default function PeopleWithContext() {  const { json } = useContext(PeopleContext);  return <PeopleRenderer json={json} />;}

Мы можем использовать значение от Provider с помощью useContext Hook. Результат выглядит следующим образом:

Анимация: Использование данных из Context (Контекста).Анимация: Использование данных из Context (Контекста).

Обратите внимание на одну важную разницу! В конце анимации выше мы нажимаем кнопку "Set new seed". При этом данные, которые хранятся в нашем Context Provider, будут заново извлечены. После этого (через 750 мс) вновь полученные данные становятся новым значением нашего Provider, а наши компоненты People перезагружаются. Как видите, все они используют одни и те же данные.

Это большое отличие от примера мемоизации (memoization), который мы рассмотрели выше. В том случае каждый компонент хранил свою копию мемоизуемых (memoized) данных с помощью useState. А в этом случае, используя и потребляя контекст, они не хранят копии, а только используют ссылки на один и тот же объект. Поэтому при обновлении значения в нашем Provider все компоненты обновляются одними и теми же данными.

. . .

useMemo

И последнее, но не менее важное, это беглый взгляд на useMemo. Этот Hook отличается от других методов, которые мы уже рассматривали, в том смысле, что это только форма кэширования на локальном уровне: внутри одного элемента компонента. Вы не можете использовать useMemo для обмена данными между несколькими компонентами по крайней мере, без таких обходных путей, как пробрасывание (prop-drilling) или внедрение зависимостей ((dependency injection) (например, React Context)).

useMemo является инструментом оптимизации. Вы можете использовать его для предотвращения пересчета значения при каждом повторном использовании вашего компонента. Документация описывает это лучше, чем могу я, но давайте рассмотрим пример:

export default function Memo() {  const getRnd = () => Math.round(Math.random() * 10000);  const [age, setAge] = useState(24);  const [randomNumber, setRandomNumber] = useState(getRnd());  const pow = useMemo(() => Math.pow(age, 2) + getRnd(), [age]);  return (    ...  );}
  • getRnd (строка 2): функция, возвращающая случайное число в диапазоне 0-10000.

  • age (строка 4): сохранение числа, отображающего возраст с useState.

  • randomNumber (строка 5): сохранение случайного числа с useState.

И, наконец, мы используем useMemo на 7-й строке. Мы мемоизуем (memoize) результат вызова функции и сохраняем его в виде переменной, называемой pow. Наша функция возвращает число, которое представляет собой сумму age, увеличенную до двух, плюс случайное число. Она имеет зависимость от переменной age, поэтому мы передаем ее в качестве зависимого аргумента вызова useMemo.

Функция выполняется только при изменении значения возраста. Если наш компонент повторно будет вызван (re-rendered) и значение age не изменится, то useMemo просто вернёт мемоизованный (memoized) результат.

В данном примере вычисление pow не очень сложное, но вы можете представить себе преимущества этого, учитывая, что наша функция становится более тяжелой и нам приходится часто визуализировать (re-rendered) наш компонент.

Последние две анимации покажут, что происходит. Во-первых, мы обновляем компонент randomNumber и не затрагиваем значение age. Таким образом, мы видим useMemo в действии (значение pow не меняется при ререндеринге (re-rendered) компонента. Каждый раз, когда мы нажимаем на кнопку randomNumer, наш компонент возвращается (re-rendered) к исходному значению:

Анимация: Много обращений (re-renders), но значение pow мемоизуется (memoized) с useMemo.Анимация: Много обращений (re-renders), но значение pow мемоизуется (memoized) с useMemo.

Однако, если мы изменяем значение age, pow получает повторный отклик (re-rendered), потому что наш useMemo вызов имеет зависимость от значения age:

Анимация: Наше мемоизованное (memoized) значение обновляется при обновлении зависимости.Анимация: Наше мемоизованное (memoized) значение обновляется при обновлении зависимости.

. . .

Заключение

Существует множество методик и утилит для кэширования данных в JavaScript. Эта статья дает только поверхностные знания, но я надеюсь, что она содержит некоторые сведения, которые вы захватите с собой на пути своего развития.

Весь программный код, использованный в этой статье, можно найти у меня в архиве на GitLab.

Спасибо, что уделили время!


Узнать подробнее о курсе "React.js Developer".

Смотреть открытый вебинар ReactJS: быстрый старт. Сильные и слабые стороны.

Подробнее..

Перевод Этапы внедрения CICD

28.10.2020 06:04:03 | Автор: admin


Jason Dorfman, MIT CSAIL


Ключевым моментом при разработке и написании кода ПО является скорейший переход на набор эксплуатационных принципов и методов, более известный как CI/CD, который соединяет непрерывную интеграцию с непрерывной поставкой. С помощью CI/CD команды разработчиков могут чаще и надежнее выкатывать изменения кода, таким образом быстрее удовлетворяя потребности бизнеса и пользователей.


Непрерывная интеграция философия написания кода и набор методов, разработанные для стимулирования команд разработки делать мелкие изменения кода и фиксировать их в репозиториях с версионированием как можно чаще. Из-за того, что большинство современных приложений требуют написания кода с использованием разных платформ и инструментов, командам нужен способ интеграции и проверки сделанных ими изменений.


Цель непрерывной интеграции создание целостного и автоматизированного способа сборки, упаковки и тестирования приложений. Целостность в процессе интеграции дает возможность командам разработчиков вносить изменения в код чаще, что ведет к улучшению совместной работы и качества ПО. Непрерывная поставка, идущая прямо за непрерывной интеграцией, автоматизирует поставку приложений на выбранное инфраструктурное окружение. Большинство команд разработчиков в настоящее время работают на разных окружениях в дополнение к производственному, включая тестовые окружения, где непрерывная доставка автоматически проверяет загруженный код на различных окружениях.


Непрерывная интеграция и непрерывная доставка охватывают культуру, набор эксплуатационных методов, а также объединенные принципы, помогающих ускорить процесс разработки ПО. Эта реализация также известна как конвейер CI/CD и считается передовым методом для команд DevOps.


Отраслевые эксперты говорят, что все больше компаний внедряют у себя CI/CD, поскольку ищут способы улучшения проектирования, разработки и поставки ПО, используемого для клиентов, или внутренних целей.


Мы определенно видим рост использования CI/CD. Я лично все время получаю вопросы насчет непрерывной разработки, тестирования и выпуска ПО. Последний опрос Gartner Agile in the Enterprise показал, что все больше команд переходят на гибкую разработку, поскольку гибкие команды имеют значительно более высокий уровень реализации непрерывной интеграции, автоматической приемки тестирования и DevOps. Я думаю, что CI самая главная точка отсчета для создания автоматических конвейеров, с нее команды обычно начинают работать. Более значимыми аспектами CD являются потребности в автоматическом тестировании и перепроектировании приложений, так что мелкие фрагменты функционала могут быть протестированы и выпущены по отдельности.
Sean Kenefick, вице-президент и аналитик в исследовательской компании Gartner

Практически все новые программные проекты, в которых участвует консалтинговая компания ServerCentral Turing Group, в той или иной степени используют CI/CD. Основными движущими силами при этом являются следующие вещи: отсутствие серверов в инфраструктуре требует интеграции CI/CD; требования безопасности нуждаются в ограничении доступа разработчиков к производственной инфраструктуре; гибкие методы требуют высокой скорости циклов развертывания и тестирования.
Josh Quint, старший директор по облачным решениям

CI/CD становится основной стратегией для многих компаний, связанных с разработкой.


Такие технические достижения, как непрерывная интеграция, комплексное автоматическое тестирование и непрерывная доставка, ранее освоенные модными стартапами, теперь успешно применяются и обычными предприятиями.
Hasan Yasar, технический директор в Software Engineering Institure при Carnegie Mellon University

Ниже перечислю несколько рекомендуемых методов реализации и обслуживания стратегии CI/CD.


Привлечение ключевых персон к CI/CD на ранних этапах


Желательно вовлечь в проект как можно раньше всех заинтересованных сотрудников. Основным преимуществом их участия будет быстрое и верное принятие решения о разработке проекта. Это должно происходить с участием всех заинтересованных сторон, чтобы основные решения могли приниматься с учетом мнения всех экспертов. Такая практика значительно снижает технический долг, накапливаемый на протяжении жизненного цикла проекта.
Hasan Yasar

К примеру, сотрудники поддержки выскажут свое мнение по поводу архитектурных решений, поэтому разработчики смогут написать инфраструктуру, одобренную поддержкой.


Выбор и внедрение правильной системы CI/CD


Системы CI/CD, доступные на рынке, могут дать ощутимую ценность для компаний, а их применение в компании, занимающейся разработкой и выпуском ПО, свидетельствует о здоровье компании. Если сборка, тестирование и поставка новых функций становится тривиальной задачей способность компании реагировать на изменения значительно улучшается. Если нужно несколько недель или даже месяцев, чтобы сделать что-то для ваших клиентов придет кто-то другой, кто сможет сделать это лучше.
Josh Komoroske, старший инженер DevOps в StackRox, поставщике технологий безопасности контейнеров

Однако производителям нужно провести достаточно исследований, чтобы вникнуть в ПО, с которым можно построить процессы CI/CD.


Попросите ответственного за техническое направление, жизненный цикл и хорошее состояние продукта, выделить немного времени на исследование экосистемы и доступных решений. Запросите обратную связь от разработчиков этого продукта. Ведь они и есть основной заказчик системы CI/CD, поскольку работают с ней ежедневно.
Josh Komoroske

Как только компания выбрала какую-либо систему, нужно избежать проблемы неиспользования.


Большинство таких решений предлагают бесплатный ознакомительный период, могут внедряться вместе с другими платформами, например GitHub. Настройте совместную работу и начинайте что-нибудь собирать. Автоматизируйте сборку, тесты, поставку. Когда люди увидят. что такие системы дают ценности их рабочим процессам, они сразу же начнут переносить свои задачи в них.
Josh Komoroske

Совместное использование автоматического тестирования и ручных подтверждений


Непрерывная поставка основана на четырех главных частях:
  • Перепроектирование для разделения
  • Автоматизация тестирования
  • Создание автоматического конвейера для процесса
  • Автоматизация создания и настройки окружений
    Эти четыре компонента общие для всех, но есть много индивидуальных методов их реализации.
    Sean Kenefick

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


Не существует самого важного набора для тестирования, они важны все. Наборы также должны совместно использоваться с другими методиками обеспечения качества, например, инструментами статического анализа, обеспечением анализа кода через PR, использованием конвейеров непрерывной интеграции.
Sean Kenefick

Удостоверьтесь, что есть ручные подтверждения на критических точках процесса поставки. Шаги с ручным подтверждением не будут давать непротестированному и неподтвержденному коду попасть в промышленное использование, либо в последующие тестовые окружения. Кроме того, у вас появляется возможность управления попадания кода в ключевые окружения.
Josh Quint

Отслеживание параметров обеспечения успешности работы CI/CD


CI/CD не работает в режиме поставил и забыл, который актуален для большинства других технологий и процессов.


Узнайте продолжительность и уровень стабильности циклов сборка/тестирование/поставка. Определите области и возможности для оптимизации. Быстро лучше, чем медленно, но надежность и правильность важнее скорости. Процессы CI/CD и связанные с ними инструменты следует рассматривать как усилители, позволяющие сократить время на разработку и тестирование, а также время вывода на рынок (TtM).
Josh Komoroske

Компании могут достичь ощутимых улучшений в разработке и проектировании при внедрении CI/CD, им следует измерять эти улучшения и делать сравнение производительности время от времени.


DevOps построен на обещании непрерывного обучения и улучшения, но этот момент упускает большинство команд на ранних этапах внедрения CI/CD. Необходимо анализировать данные, получаемые от инструментов CI/CD, чтобы определить ключевые показатели эффективности, цели производительности и аналитику, измеряемую на протяжении всего процесса DevOps.
Farid Roshan, глава Altimetrik, поставщика ПО для проектирования и совместной работы

Понимание движущих сил бизнеса для внедрения CI/CD, мысли о будущих потребностях


Важно понимать, почему действительно нужно внедрять CI/CD. Только в этом случае они смогут позволить своим командам разработчиков получить нужные навыки для достижения ключевых целей.


Если все сделано правильно, то CI/CD может улучшить продуктивность разработчиков, провести оптимизацию фреймворка для поставки, эксплуатационную эффективность и гибкую трансформацию. Первое поколение платформ CI/CD разработано в качестве сервиса оркестровки, соединяющего процессы жизненного цикла продукта для увеличения продуктивности. Однако такая платформа может и не дать высокого ROI, зависящего от времени, требуемого для написания кода. Современные возможности CI/CD добавили модульную архитектуру, с которой возможно реализовать подключение моделей на лету, а также настраиваемость конвейеров для поддержки различных фреймворков поставки.
Farid Roshan

Правильная реализация конвейера-как-кода дает возможность командам инженеров разработать расширенные функции, отвечающие текущим потребностям бизнеса. Но также важно предсказывать будущие потребности.


Развивайте возможности CI/CD для целей вашего бизнеса. Внедрение DevOps CI/CD в отрыве от основы текущих процессов приведет к фрагментарному внедрению инструмента, отсутствию стандартизации, а также минимальному ROI при обеспечении гибкости доставки. Эта ошибка будет лавинной для бизнеса.
Farid Roshan

Автоматизация везде, где это возможно


Компании должны автоматизировать все, что можно автоматизировать в качестве части CI/CD, а также четко обозначить те вещи, которые не будут автоматизированы. Автоматизация один из столпов DevOps, наиболее ценная вещь, получаемая от реализации DevOps, делающая возможным CI/CD.
Hasan Yasar

Подход Agile-DevOps, стал возможным благодаря практике инфраструктуры-как-кода (IaC), т.е. управления частями инфраструктуры, сетями, виртуальными машинами, балансировщиками нагрузки с использованием тех же методов управления версиями, которыми пользуются команды DevOps для исходного кода, включая автоматизацию различных окружений.


Компания может брать процессы и методы, приводящие к IaC, включая управление настройками, установку окружений, и так далее. Цель принимать все автоматизированные процедуры как код, хранимый в защищенной системе контроля версий.

От редакции: О внедрении CI/CD, приемах работы с Gitlab CI и лучших практиках построения пайплайна спикеры Слёрма говорят в практическом видеокурсе CI/CD на примере Gitlab CI. До 3 декабря 2020 курс доступен по цене предзаказа. Присоединяйтесь!

Подробнее..

Внедрение CICD в чем основная задача пайплайна и как сделать лучше жизнь разработчиков

26.11.2020 04:22:27 | Автор: admin


О своём опыте построения пайплайнов, правильных и неправильных подходах к CI/CD, здоровых профессиональных конфликтах и реализации GitOps в неидеальном мире рассказывают спикеры курса Слёрма по CI/CD Тимофей Ларкин и Александр Швалов.


Кто говорит


Тимофей Ларкин
Руководил направлением автоматизации в дирекции BigData компании X5 Retail Group, строил платформу для разработки и хостинга продуктов. Сейчас работает платформенным инженером Тинькофф.


Александр Швалов
Инженер Southbridge, настраивает и сопровождает проекты на Kubernetes. Помогал настраивать CI/CD как для небольших, так и для крупных компаний. Certified Kubernetes Administrator.


Почему тема настройки CI/CD до сих пор остаётся актуальна? Почему до сих пор все не научились это делать?


Т: Я думаю, по той же причине, по которой уже одиннадцать лет существует слово DevOps, но некоторые компании и коллективы только-только запускают так называемую DevOps-трансформацию. По той же причине, что всегда есть отстающие, которые пока в группе Low Performеrs. Не все ещё научились. Не всем это вдруг стало нужно, не все так быстро разрабатывали внутри себя технологическую экспертизу.


То есть дело не в том, что тема сама по себе невозможна для реализации, а в том, что просто кто-то ещё последовательно до неё не дошёл?


Т: Да, всё так.


А: Я добавлю, что есть некоторые компании, стартапы, где два человека, допустим, сидят, и им пока не нужен CI/CD. Может быть, они о нём знают, но пока без него обходятся. И внедрение это должно быть на каком-то этапе, когда проект вырос до точки, где это необходимо. Тогда это принесёт больше плюсов, чем минусов. Когда есть только один талантливый программист, ему намного быстрее будет разрабатывать без CI/CD. Ну, и да, отсталость некоторых проектов. Я сам работаю с клиентами, и у них есть сайты с большой посещаемостью, куда они заходят и в середине рабочего дня вешают заглушку и начинают править код. Прямо на продакшене.


Какие это проекты?


А: Да просто интернет-магазины. Небольшие, естественно. В больших очень критичны простои. Там используют серьёзные технологии. А небольшие может, не слышали, может, им это неинтересно. Мы иногда рассказываем, что и как можно настроить, но без особого энтузиазма воспринимают. Мол, старое работает, и ладно.


До вопроса внедрения мы ещё дойдём. Расскажите о своём опыте построения CI/CD, что это были за проекты?


Т: Я около двух лет назад пришёл в X5 Retail Group как, на тот момент, единственный сотрудник нового подразделения, и на мне висела задача построить платформу для разработки, чтобы разработчикам дирекции больших данных было, где собирать свой код и где его запускать. Там достаточно много разных проектов. Какие-то более будничные: прогнозирование оптимальных цен, оптимальных промо-акций (вроде скучное, но приносит прибыль). И что-то более хайповое, вплоть до проектов по компьютерному зрению.


Технологии были разные. В основном для бэкендеров это Java, для фронтендеров это React. Ну, и для дата-сайентистов Python (Anaconda, Jupyter Notebook и тому подобное). Я должен был создать для них эту самую платформу разработки. То есть, CI/CD-серверы (у нас был GitLab), Kubernetes заставить всё это работать в связке и помочь продуктовым командам начать этим эффективно пользоваться.


Два года назад это началось и? Процесс завершился?


Т: На сегодняшний день я уже в X5 не работаю, но там ребята уже активно развились, очень хорошо освоились. Естественно, дирекция больших данных сейчас и то, что было два года назад это совершенно разные вещи. По количеству рост сотрудников, наверное, раз в 5-6. Ну, это была очень молодая дирекция на тот момент. Она очень быстро росла. И по компетенции, по парку серверов на этой рантайм платформе, по всему прочему рост был на порядки.


И люди тоже очень сильно компетенций набрались. Как я говорил, тогда я был единственным сотрудником отдела, а сейчас там примерно 10 человек. И были какие-то измеряемые успехи. Я воспроизводил исследование Ускоряйся, которое лежит в основе методики ежегодных отчётов State of DevOps, и по результатам этого исследования в масштабах одной только дирекции успехи были.


Александр, какой у вас опыт?


А: У меня опыт построения CI/CD первый был на третьем или на четвёртом потоке Слёрма, где я участвовал в качестве студента. Ведь Слёрм изначально задумывался как средство обучения сотрудников Southbridge, а я работал в Southbridge и как раз на одном из потоков плотно познакомился с CI/CD. До этого у нас было несколько клиентов с не совсем правильными подходами к CI/CD, а на обучении я увидел такой конкретный, цельный пример, и потом он мне очень пригодился.


У нас пришел клиент, ему нужно было мигрировать из Docker Swarm в Kubernetes некий стек и плюс распилить монолит. Там были уже несколько контейнеризованных микросервисов и плюс был монолит, который разработчики пилили и добавляли микросервисы, и вот это все мы заворачивали в Kubernetes. Поэтому туда я взял пример нашего CI/CD из Слёрма. Он простенький, но вполне себе рабочий. И в итоге мы дошли до того, что последние микросервисы разработчики деплоили уже сами, без нашего участия. Мы всё построили и отладили, а дальше они уже сами всё по шаблонам делали.


Если по этапам описать проделанную вами работу, в чем она заключалась? Как вы дошли от нулевой точки до момента, когда команда уже сама могла что-то делать?


А: Сначала мы адаптировали практически вручную то, что уже было в Docker Swarm микросервисы. Потребовался небольшой допил конфигурации. Плюс, helm-чарты написали первые. Использовался Kubernetes. Helm 2 на тот момент ещё был популярен. Ну и GitLab CI. После этого разработчики задавали множество вопросов, иногда делали не так, как мы задумывали. Мы поправляли их. У нас не было прямо тесной связи, мы иногда приходили и советовали, где как лучше сделать, чтобы работало. Таким путем проб и ошибок пришли к тому, что они теперь без нас отлично справляются.


До этого вы упомянули неправильные подходы. Что это было?


А: В целом неправильный подход для мелких проектов, наверное, оправдан. Потому что там не было CI-инструмента. У нас в курсе будут описаны некоторые уже устоявшиеся инструменты (online, self-hosted-решения). А там было проще некуда: задание по расписанию, git pull из репозитория с кодом. Буквально каждые две минуты он делает git pull. И когда разработчик в нужную ветку пушит изменения, он понимает, что это попадёт на продакшн. Т.е. через вот этот промежуток времени 1-2 минуты скрипт сработал, и всё попало на продакшн. Разработчику не нужно было самому ходить. Это такой небольшой пример CI/CD. Естественно, о тестах говорить не приходилось, всё было на совести разработчика.


Какие проблемы могут возникнуть при таком подходе? Ошибки?


А: Да, плюс откат. Если мы из этой ветки пушим постоянно, то чтобы откатиться, нужно будет в ту же ветку запушить уже более поздним коммитом нужную версию, уже исправленную. А не вернуться к предыдущему коммиту или предыдущему релизу/тегу.


Т: Тут еще, понимаете, это очень здорово работает, пока там действительно стартап из двух человек. И один только финансами занимается, а кодит только второй. Зачем ему тогда сильно следить за качеством своего кода? Зачем ему выстроенный CI/CD процесс? Он и так отлично знает, что у него где лежит. Проблемы начинаются, когда такую модель работы переносят на командную разработку, и там есть 2-3-4 сеньора, которые всё отлично знают, но никто не может начать с ними работать, потому что они не столь ответственно относились к качеству кода, не запускали тесты. Вроде и так всё понятно, но всегда тяжело учесть, что придёт человек со стороны а в больших компаниях это постоянно случается которому будет сложно объяснить, что тут вообще происходит. Цель CI/CD не просто автоматизировано допихать код до продакшена, но и следить за его качеством.


Мне кажется, это даже не основная цель пайплайна собрать какой-то артефакт, Docker-образ и задеплоить. В любом случае, пайплайн должен уметь делать это безупречно. Потому что это такая типовая задача, которую мы должны легко делать каждый день с нашим кодом. Но вообще, в процессе разработки продукта полезно иметь здоровый профессиональный конфликт. Это конфликт между разработчиками и инженерами по обеспечению качества. И пайплайн тоже должен стоять на страже качества кода. Чтобы тыкать разработчика носом и говорить: Так, вот тут у тебя код не по стандартам отформатирован. Вот тут линтер ругается, тут юнит-тесты не проходят. Давай откатывай и переделывай.

Если пайплайн просто собирает как-нибудь код и потом деплоит его, мы не знаем, что, собственно, задеплоили. Нормально или фигня. Может, там десять релизов уже, и каждый всё больше ломал наш код.


А как построить такую систему? Нужно, чтобы разработчики договорились о стандартах: мы все согласны, что вот так делаем, а вот так не делаем?


Т: Да, нужно прийти к соглашению, что мы считаем плохим/хорошим, как мы будем делать. Но в целом, это спор ни о чем. Не так важно, до чего вы договоритесь у вас будут табы или пробелы. Это все второстепенно. Выберите уже что-нибудь. Это лучше, чем ничего. В этом плане Golang такой интересный пример. Он не стал давать разработчикам волю самим выбирать, какое будет соглашение о качестве. Он просто сказал: Ок, у нас отступы табами, табы шириной 8 символов. И всё, не колышет. Это встроено прямо в утилиты самого Golang. Есть такое высказывание: Все его ненавидят, но при этом он самый лучший. Потому что хоть какой-то стандарт есть. Встроить проверку соответствия кода выбранным стандартам в пайплайн это буквально две строчки.


Как обеспечить контроль выполнения стандартов?


Т: Мне не приходит на ум ни один язык, где нельзя какие-то юнит-тесты сделать. Как правило, они делаются обычно чуть ли не средствами самого компилятора. Это одна строчка. Если нет юнит-тестов, когда первый будет написан, он автоматически будет выполняться. Потом, если это компилируемый код, тогда сам факт, что компиляция прошла успешно, тоже о чём-то да говорит.


Значит, есть несколько таких ступенек?


Т: Да. Всегда принцип 20/80. 20% усилий дают 80% успеха.


А: Тут упомянули проверку кода. Это достаточно важно, и многие инструменты содержат в своём названии как раз CI. Travis CI, GitLab CI. И это очень важно проверить и программиста носом натыкать, это экономия труда тестировщиков. Может, потом код скомпилируется, запустится, даже будет первое время выглядеть нормально, но потом тестировщик найдёт ошибку. А если это сделает автоматика, это намного быстрее и экономия труда, половины рабочего дня тестировщика.


Вы сказали программиста носом натыкать. Это тот самый конфликт между разработкой и QA, о котором говорил Тимофей?


А: Могу привести свой пример, поскольку работаю с CI/CD каждый день, но не с кодом, а с конфигурациями. У нас есть линтеры лишний пробел поставил, он уже ругается. Иногда злишься, ведь это просто формальность, ни на что не повлияет, но это приучает к качеству. И стандарты эти нужны для обеспечения командной работы в том числе. Чтобы новый человек пришел и быстро разобрался.


Получается, весь процесс настройки CI/CD как бы против программиста. Разработчик раньше был этаким свободным художником, а теперь приходит DevOps-инженер и говорит ему, как работать.


А: Можно провести аналогию с конвейером. Если норма у рабочего на конвейере пять деталек в час, а он такой стахановец и делает десять. Это уже может быть непредсказуемость, если мы всегда будем считать, что он делает десять, хотя норма пять. Поэтому лучше пусть стабильно делает пять, но качественно. Можно фигачить код без стандартов, он будет работать, но новый человек не въедет быстро. Поэтому в командной работе есть ограничения, чтобы ото всех можно было получить одинаково стабильную работу. А не так, что один вкалывает, а другой сидит.


Т: А если сеньор проверяет код джуна и говорит: Слушай, а тут вот у тебя функция может вернуть исключение, а ты его не проверяешь. Это сеньор тогда против джуна? А что меняется, если то же самое делает автоматика? Что сеньор, что автоматика они против плохого кода, а не против разработчика.


Давайте мы теперь чуть отступим и поговорим про внедрение CI/CD. Как компании и команды приходят к тому, что пора что-то менять? Ошибки слишком частые, порядка нет, что-то ещё?


Т: Это очень по-разному случается. Вот мой опыт в X5 был такой, что была полная поддержка со стороны менеджмента, но при этом есть менеджмент всей дирекции, а есть отдельные продуктовые команды, у которых некое двоевластие. С одной стороны, есть руководитель отдела разработки, который, наверное, ратует за поставку качественного кода, но, с другой стороны, это продуктовая команда, у них есть дедлайны для поставки фич, и не всегда ясно, что поставить в приоритет. Конечно, нет откровенно глупых людей, которые говорят, что весь этот ваш DevOps не важен, нам нужно фичи пилить. Но при этом в разговорах проскакивает моментами. Мол, ну, я не знаю, у меня сейчас есть бюджет на одну ставку, и для меня вывод очевиден, кого я возьму DevOps или ещё одного разработчика. Мне нужно разрабатывать, так что я возьму разработчика.


Как сделать хорошую мину при плохой игре? Поскольку у нас есть такой инфраструктурный отдел, который ещё в какой-то степени DevOps-евангелисты, то есть отдел, которым я руководил в X5, лучшее, что можно сделать, это облегчить командам внедрение этих пайплайнов, этого CI/CD. Обучать людей до тех пор, пока это возможно, но лучше всего что-то сделать за них. Зашаблонизировать типовые действия. Например, даже банально собрать докер-образ и запушить его в репозиторий. Это нужно авторизоваться в docker registry. Рассчитать, с каким тегом мы соберем докер-образ. Это docker build, потом пуш несколько раз. Возможно, если мы хотим кэши, то нужно сначала скачать старый образ, который уже был, использовать его как кэш, потом закачать новый. Это куча рутины, которая может растянуться строчек на пятнадцать, но это всё однотипно.


Если инфраструктурная команда понимает немного в DevOps, она осознаёт, что это её задача. Сделайте Developer Experience получше. Зашаблонизируйте это, чтобы умещалось в три строчки, а не в пятнадцать. Тогда разработчики будут мыслить не категориями: надо спулить образ, собрать, туда-сюда. А категориями: а вот здесь Docker. Просто один блок, модульный такой. И им будет легче. Они тогда смогут абстрагироваться от деталей и больше заниматься своей непосредственной работой. А именно писать код. В этом плане DevOps он в том, чтобы фасилитировать, предоставлять разработчикам возможность лучше делать свою работу.
И таким образом снижать сопротивление.

А: Отвечу на тот же вопрос со своей стороны. У меня пример внедрения не из мира разработки, больше из мира администрирования. У нас в один прекрасный момент сказали: Мы вот подошли к тому, что откладывать нельзя. Базис мы подготовили для вас. Теперь все новые проекты вы будете создавать вместо старого пути по CI/CD. Вот у вас есть шаблончик, создаете в GitLab и работаете с ним. Каждая команда будет вольна его улучшать. Так и внедряли. Достаточно императивно. В некоторых проектах, когда этот путь нёс больше вреда, чем пользы, мы откатывались на старую версию, но сейчас половина проектов работают через CI/CD. Мы управляем конфигурациями серверов через GitLab CI. Точно так же, как у разработчиков, там есть проверки, линтеры.


Раз уж заговорили про администрирование, поговорим про GitOps. Что это такое, и какое значение имеет: это всё-таки хайп или полезность?


А: Мало что могу сказать про GitOps. Мое мнение такое, что это достаточно хайповое слово. В последнее время я много его слышу. Три года назад так хайповали на DevOps, так что GitOps для меня одно из слов, примазавшихся к DevOps. Для меня это больше хайп.


Это вообще о том, что вся правда хранится в Git. Там и управление конфигурациями серверов, Infrastructure-as-Code, и код проекта, который потом на эти сервера поедет, и описание процесса, как мы с исходного кода получаем приложение на серверах. Так это я понимаю. Возможно, Тимофей меня дополнит, исправит.


Т: GitOps, мне кажется, чуть более честное словечко, чем все эти DevOps, DevSecOps и так далее. Потому что оно значит почти буквально то, что и говорит. Это именно ведение своих действий по эксплуатации своего софта, своей инфраструктуры через Git. Вся правда хранится в Git.


Что это на практике значит? Вроде как мы запушили какой-то код в наш репозиторий, автоматически запустился пайплайн. Что-то произошло, допустим, какие-то манифесты отправились в Kubernetes. И вот у нас то, что мы запушили в Git, это теперь то, что находится в Kubernetes. В принципе, это тоже GitOps, хотя не всегда его так называют. В частности, это так называемая push-модель, когда мы информацию из репозитория толкаем на продакшн.


Еще бывает так называемая pull-модель. Когда, если речь идет о Kubernetes, то у нас там какой-то агент стоит, который мониторит изменения в репозиториях, и если видит, что там что-то закомитили, что-то изменилось, то он стягивает эти изменения. Он умеет и Helm, и Kustomize делать, и просто манифесты ямликами подтягивать. И опять же отправляет их в Kubernetes.


Некоторые пропоненты GitOps вовсе закрывают любое редактирование в Kubernetes и позволяют изменять состояние кластера, только подтягивая изменения из Git. Если этого не делать, всегда есть риск, что из-за чьих-то ручных действий состояние кластера и то, что описано в репозитории разъедется. Кто-то там ручками что-то поменял, а в Git ничего не поменялось. Поэтому частенько говорят про GitOps именно в контексте pull-модели, когда, ну, поменял ты что-то в Kubernetes, ничего страшного, потому что автоматика в ближайшие полчаса все равно вернет все, как описано в Git.


Всё это особенно важно в деле управления конфигурацией, потому что, если есть такая система, если забывать периодически проверять, что состояние серверов такое, как описано в коде конфигурации, то вскоре может прийти осознание, что мы не уверены, безопасно ли запускать код управления конфигурацией. Мы не помним, какие изменения вручную наделали, и что будет, если мы попытаемся привести наши сервисы к желаемому состоянию.


К примеру, смежный отдел, который управлял Data Lake в X5, быстро пришёл к тому, что у них вся конфигурация из двух сотен машин управлялась через Ansible, а он запускался каждые 30 минут, как пайплайн в GitLab. Это пример более-менее правильного применения GitOps.


Ну, и те инструменты, которые для GitOps используются, они ещё в какой-то мере нам подсвечивают: а у нас задеплоено именно то, что мы хотим? Иногда они не возвращают автоматически состояния, а просто зажигается желтый или красный светофор: Оп, ребята, у вас рассинхронизировалось состояние тут и тут.


Александр, когда вы говорили о том, как строите процесс работы с клиентами в Southbridge, вы упоминали что-то похожее на GitOps. Настройка конфигурации через описание в Git, это не то же самое?


А: В идеальном мире да. Но у софта зачастую очень много настроек. И чтобы в каждой ручечку/переключатель/ползунок поменять, роль управления конфигурацией должна быть очень развесистая, раскидистая. Либо шаблонизированная. Иногда бывает, что настройки просто нет, и мы идем вручную поправляем. Разработка не успевает за эксплуатацией. Потому что иногда задачи бывают критичные. А чтобы всё разработать, у нас просто нет времени. Но в идеальном случае мы делаем именно то, что описал Тимофей.


Тимофей, а подход GitOps учитывает это обстоятельство неидеального мира?


Т: Это тяжело, конечно. Потому что нам надо бизнес делать, бабки зарабатывать. Казалось бы, вот она, ручка, сходи и поменяй, надо же. Есть потребность, а тут какой-то скрипт ещё писать, дорабатывать helm-чарты. Поэтому да, есть соблазн всё быстренько сделать руками.
Чтобы и бизнес-потребности учесть и себе codebase не испортить, можно хотя бы завести тикет, что вот тут вручную настраиваемое значение, но это баг. Мы положим тикет в бэклог, потом обязательно вернемся и допилим тут автоматизацию. Главное не потерять места, где мы руками настраивали.


В чём ключевые преимущества подхода GitOps?


Т: Основное мы достоверно знаем, что у нас запущено в продакшене. Что все четко описано в репозитории, и не возникает сомнений, что кто-то руками поменял.


А: Когда большая команда, это очень важно, что все могут в любой момент посмотреть и увидеть, какая сейчас конфигурация работает на нужном сервере. Потому что если там 1-2 человека, они могут всегда договориться, а когда 15 человек, GitOps сильно экономит время. Не надо ходить, опрашивать, выяснять, откуда ноги растут у несоответствий.


Чем GitOps отличается от подхода Infrastructure-as-Code?


А: Это не только инфраструктура, но еще и приложение, как код. Они хранятся в единой точке. Может, в разных репозиториях, но в одном инстансе GitLab. Можно легко посмотреть состояние инфраструктуры и приложения. Плюс, в идеальном мире может быть вообще связана инфраструктура с кодом. Мы создали новый репозиторий, настроили с нуля хитрый пайплайн, запушили код и он сам пошёл, создал себе инфраструктуру где-нибудь в облаке и задеплоил туда приложение, которое мы туда написали. Это идеальный, конечно, случай, но думаю, где-то это работает. Например, в больших компаниях.


Т: Да, там предлагают даже держать отдельно несколько репозиториев. Один это просто сам код приложения, в котором собирается образ или бинарник. Второй репозиторий туда генерируются, допустим, манифесты для Kubernetes. Третий это такой большой репозиторий, который нам рассказывает, что в нашем кластере манифест из этого репозитория за таким-то тегом, из этого такой-то версии. Он уже просто по номерам версий описывает, что вообще в нашем кластере запущено. На это иногда даже автоматику натягивают: изменили приложение, только код, повесили на него новый тег, а там потом автоматически новый манифест запушился в репозиторий с манифестами, и нужная строчка с нужной версией изменилась в том месте репозитория, которое описывает общее состояние кластера.


Это такая идеальная система?


Т: Ну, да.


CI/CD это такая штука, которую один раз настроил и забыл, или это процесс, который нужно поддерживать?


Т: И да, и нет. Когда он только внедряется, не бывает сразу идеально. Когда в X5 я внедрял, то начальник отдела разработки спрашивал у разработчиков, сколько времени в неделю они тратят на обслуживание их CI/CD. Кто-то отвечал: А что там обслуживать? Вот мы настроили и забыли. И какое-то время это работает. Если сделать сходу правильно, можно сделать очень модульные блоки. И потом не сильно трогать нижележащий код, который это делает, а просто появился новый проектик/микросервис, подключили к нему типовые модульные блоки и поехали дальше. Но пока все учатся, что-то допиливается. Приходится на первых порах долго и мучительно внедрять новые хорошие практики в трудно обслуживаемый код. Дальше уже полегче.


А в больших компаниях как обычно происходит? Приходит DevOps, помогает всё это настроить и остается в команде, или разработчики перенимают на себя его функции, а DevOps уходит в другую команду? Или есть отдел DevOps?


Т: Все очень по-разному. У меня в X5 были продуктовые команды очень разных способностей. Какие-то хорошо въезжали в процесс, и редко надо было им помогать. Были более слабые. К ним привязывали инженера, который помогал писать пайплайны. Работал, в некоторой степени, приходящим релиз-инженером в их команде. Но в X5 порядка 9-10 DevOps обслуживали потребности где-то 200 техспециалистов.


Сейчас я работаю в Тинькофф, тоже в платформенной команде, но там масштабы немного другие. Нас 8 человек, а разработчиков тысячи полторы. И невозможно предоставлять каждой команде DevOps как сервис. Поэтому там предполагается, что команда сама добывает эту экспертизу или нанимает себе DevOps. Либо сами разработчики этому обучаются.


А: Моя версия такая, что да, вначале идет активная разработка. Мы программируем пайплайн, что за чем будет идти, потом ситуация может устаканиться. Если в архитектуре проекта нет глобальных изменений, всё может работать год без правок. Но в мире все меняется. Микросервисы могут быть переписаны за две недели. И если их переписали на другом языке программирования, то тесты выкидываем и пишем новые. Поэтому CI/CD тоже требует обслуживания.


Ну и добавлю, что у разработчиков разная компетенция. Кому-то постоянно нужна помощь, а кому-то нет. Вот у нас был пример с одним из клиентов. Мы им настроили базовые CI/CD, всё показали. Через какое-то время они к нам приходят и говорят: А мы вот переписали всё по-своему. Мы только и ответили: Ух ты, молодцы. Они просто взяли все в свои руки.

Подробнее..

Перевод Что такое CICD? Разбираемся с непрерывной интеграцией и непрерывной поставкой

13.08.2020 22:14:38 | Автор: admin
В преддверии старта курса CI/CD на AWS, Azure и Gitlab подготовили для вас перевод полезного материала.



Непрерывная интеграция (Continuous Integration, CI) и непрерывная поставка (Continuous Delivery, CD) представляют собой культуру, набор принципов и практик, которые позволяют разработчикам чаще и надежнее развертывать изменения программного обеспечения.

CI/CD это одна из DevOps-практик. Она также относится и к agile-практикам: автоматизация развертывания позволяет разработчикам сосредоточиться на реализации бизнес-требований, на качестве кода и безопасности.

Определение CI/CD


Непрерывная интеграция это методология разработки и набор практик, при которых в код вносятся небольшие изменения с частыми коммитами. И поскольку большинство современных приложений разрабатываются с использованием различных платформ и инструментов, то появляется необходимость в механизме интеграции и тестировании вносимых изменений.

С технической точки зрения, цель CI обеспечить последовательный и автоматизированный способ сборки, упаковки и тестирования приложений. При налаженном процессе непрерывной интеграции разработчики с большей вероятностью будут делать частые коммиты, что, в свою очередь, будет способствовать улучшению коммуникации и повышению качества программного обеспечения.

Непрерывная поставка начинается там, где заканчивается непрерывная интеграция. Она автоматизирует развертывание приложений в различные окружения: большинство разработчиков работают как с продакшн-окружением, так и со средами разработки и тестирования.

Инструменты CI/CD помогают настраивать специфические параметры окружения, которые конфигурируются при развертывании. А также CI/CD-автоматизация выполняет необходимые запросы к веб-серверам, базам данных и другим сервисам, которые могут нуждаться в перезапуске или выполнении каких-то дополнительных действий при развертывании приложения.

Непрерывная интеграция и непрерывная поставка нуждаются в непрерывном тестировании, поскольку конечная цель разработка качественных приложений. Непрерывное тестирование часто реализуется в виде набора различных автоматизированных тестов (регрессионных, производительности и других), которые выполняются в CI/CD-конвейере.

Зрелая практика CI/CD позволяет реализовать непрерывное развертывание: при успешном прохождении кода через CI/CD-конвейер, сборки автоматически развертываются в продакшн-окружении. Команды, практикующие непрерывную поставку, могут позволить себе ежедневное или даже ежечасное развертывание. Хотя здесь стоит отметить, что непрерывная поставка подходит не для всех бизнес-приложений.

Непрерывная интеграция улучшает коммуникации и качество


Непрерывная интеграция это методология разработки, основанная на регламентированных процессах и автоматизации. При внедренной непрерывной интеграции разработчики часто коммитят свой код в репозиторий исходного кода. И большинство команд придерживается правила коммитить как минимум один раз в день. При небольших изменениях проще выявлять дефекты и различные проблемы, чем при больших изменениях, над которыми работали в течение длительного периода времени. Кроме того, работа с короткими циклами коммитов уменьшает вероятность изменения одной и той же части кода несколькими разработчиками, что может привести к конфликтам при слиянии.

Команды, внедряющие непрерывную интеграцию, часто начинают с настройки системы контроля версий и определения порядка работы. Несмотря на то что коммиты делаются часто, реализация фич и исправление багов могут выполняться довольно долго. Для контроля того, какие фичи и код готовы существует несколько подходов.

Многие используют фича-флаги (feature flag) механизм для включения и выключения функционала в рантайме. Функционал, который еще находится в стадии разработки, оборачивается фича-флагами и развертывается из master-ветки в продакшн, но отключается до тех пор, пока не будет полностью готов к использованию. По данным недавнего исследования 63 процента команд, использующих фича-флаги, говорят об улучшении тестируемости и повышении качества программного обеспечения. Для работы с фича-флагами есть специальные инструменты, такие как CloudBees Rollout, Optimizely Rollouts и LaunchDarkly, которые интегрируются в CI/CD и позволяют выполнять конфигурацию на уровне фич.

Другой способ работы с фичами использование веток в системе контроля версий. В этом случае надо определить модель ветвления (например, такую как Gitflow) и описать как код попадает в ветки разработки, тестирования и продакшена. Для фич с длительным циклом разработки создаются отдельные фича-ветки. После завершения работы над фичей разработчики сливают изменения из фича-ветки в основную ветку разработки. Такой подход работает хорошо, но может быть неудобен, если одновременно разрабатывается много фич.

Этап сборки заключается в автоматизации упаковки необходимого программного обеспечения, базы данных и других компонент. Например, если вы разрабатываете Java-приложение, то CI упакует все статические файлы, такие как HTML, CSS и JavaScript, вместе с Java-приложением и скриптами базы данных.

CI не только упакует все компоненты программного обеспечения и базы данных, но также автоматически выполнит модульные тесты и другие виды тестирования. Такое тестирование позволяет разработчикам получить обратную связь о том, что сделанные изменения ничего не сломали.

Большинство CI/CD-инструментов позволяет запускать сборку вручную, по коммиту или по расписанию. Командам необходимо обсудить расписание сборки, которое подходит для них в зависимости от численности команды, ожидаемого количества ежедневных коммитов и других критериев. Важно, чтобы коммиты и сборка были быстрыми, иначе долгая сборка может стать препятствием для разработчиков, пытающихся быстро и часто коммитить.

Непрерывное тестирование это больше, чем автоматизация тестирования


Фреймворки для автоматизированного тестирования помогают QA-инженерам разрабатывать, запускать и автоматизировать различные виды тестов, которые помогают разработчикам отслеживать успешность сборки. Тестирование включает в себя функциональные тесты, разрабатываемые в конце каждого спринта и объединяемые в регрессионные тесты для всего приложения. Регрессионные тесты информируют команду: не сломали ли их изменения что-то в другой части приложения.

Лучшая практика заключается в том, чтобы требовать от разработчиков запускать все или часть регрессионных тестов в своих локальных окружениях. Это гарантирует, что разработчики будут коммитить уже проверенный код.

Регрессионные тесты это только начало. Тестирование производительности, тестирование API, статический анализ кода, тестирование безопасности эти и другие виды тестирования тоже можно автоматизировать. Ключевым моментом является возможность запуска этих тестов из командной строки, через веб-хук (webhook) или через веб-сервис и возврат результата выполнения: успешный был тест или нет.

Непрерывное тестирование подразумевает не только автоматизацию, но и интеграцию автоматического тестирования в конвейер CI/CD. Модульные и функциональные тесты могут быть частью CI и выявлять проблемы до или во время запуска CI-конвейера. Тесты, требующие развертывания полного окружения, такие как тестирование производительности и безопасности, часто являются частью CD и выполняются после разворачивания сборок в целевых средах.

CD-конвейер автоматизирует поставку изменений в различные окружения


Непрерывная поставка это автоматическое развертывание приложения в целевое окружение. Обычно разработчики работают с одним или несколькими окружениями разработки и тестирования, в которых приложение развертывается для тестирования и ревью. Для этого используются такие CI/CD-инструменты как Jenkins, CircleCI, AWS CodeBuild, Azure DevOps, Atlassian Bamboo, Travis CI.

Типичный CD-конвейер состоит из этапов сборки, тестирования и развертывания. Более сложные конвейеры включают в себя следующие этапы:

  • Получение кода из системы контроля версий и выполнение сборки.
  • Настройка инфраструктуры, автоматизированной через подход инфраструктура как код.
  • Копирование кода в целевую среду.
  • Настройка переменных окружения для целевой среды.
  • Развертывание компонентов приложения (веб-серверы, API-сервисы, базы данных).
  • Выполнение дополнительных действий, таких как перезапуск сервисов или вызов сервисов, необходимых для работоспособности новых изменений.
  • Выполнение тестов и откат изменений окружения в случае провала тестов.
  • Логирование и отправка оповещений о состоянии поставки.


Например, в Jenkins конвейер определяется в файле Jenkinsfile, в котором описываются различные этапы, такие как сборка (build), тестирование (test) и развертывание (deploy). Там же описываются переменные окружения, секретные ключи, сертификаты и другие параметры, которые можно использовать в этапах конвейера. В разделе post настраивается обработка ошибок и уведомления.

В более сложном CD-конвейере могут быть дополнительные этапы, такие как синхронизация данных, архивирование информационных ресурсов, установка обновлений и патчей. CI/CD-инструменты обычно поддерживают плагины. Например, у Jenkins есть более 1500 плагинов для интеграции со сторонними платформами, для расширения пользовательского интерфейса, администрирования, управления исходным кодом и сборкой.

При использовании CI/CD-инструмента разработчики должны убедиться, что все параметры сконфигурированы вне приложения через переменные окружения. CI/CD-инструменты позволяют устанавливать значения этих переменных, маскировать пароли и ключи учетных записей, а также настраивать их во время развертывания для конкретного окружения.
Также в CD-инструментах присутствуют дашборды и отчетность. В случае сбоя сборки или поставки они оповещают об этом. При интеграции CD с системой контроля версий и agile-инструментами облегчается поиск изменений кода и пользовательских историй, вошедших в сборку.

Реализация CI/CD-конвейеров с Kubernetes и бессерверными архитектурами


Многие команды, использующие CI/CD-конвейеры в облаках используют контейнеры, такие как Docker, и системы оркестрации, такие как Kubernetes. Контейнеры позволяют стандартизировать упаковку, поставку и упростить масштабирование и уничтожение окружений с непостоянной нагрузкой.

Есть множество вариантов совместного использования контейнеров, инфраструктуры как код и CI/CD-конвейеров. Подробнее изучить это вы можете в статьях Kubernetes with Jenkins и Kubernetes with Azure DevOps.

Архитектура бессерверных вычислений представляет собой еще один способ развертывания и масштабирования приложений. В бессерверном окружении инфраструктурой полностью управляет поставщик облачных услуг, а приложение потребляет ресурсы по мере необходимости в соответствии с его настройками. Например, в AWS бессерверные приложения запускаются через функции AWS Lambda, развертывание которых может быть интегрировано в CI/CD-конвейер Jenkins с помощью плагина.

CI/CD обеспечивает более частое развертывание кода


Итак, подведем итоги. CI упаковывает, тестирует сборки и оповещает разработчиков, если что-то пошло не так. CD автоматически разворачивает приложения и выполняет дополнительные тесты.

CI/CD-конвейеры предназначены для организаций, которым необходимо часто вносить изменения в приложения с надежным процессом поставки. Помимо стандартизации сборки, разработки тестов и автоматизации развертываний мы получаем целостный производственный процесс по развертыванию изменений кода. Внедрение CI/CD позволяет разработчикам сосредоточиться на улучшении приложений и не тратить силы на его развертывание.

CI/CD является одной из DevOps-практик, поскольку направлена на борьбу с противоречиями между разработчиками, которые хотят часто вносить изменения, и эксплуатацией, требующей стабильности. Благодаря автоматизации, разработчики могут вносить изменения чаще, а команды эксплуатации, в свою очередь, получают большую стабильность, поскольку конфигурация окружений стандартизирована и в процессе поставки осуществляется непрерывное тестирование. Также настройка переменных окружения отделена от приложения и присутствуют автоматизированные процедуры отката.

Эффект от внедрения CI/CD-конвейеров можно измерить в виде ключевых показателей эффективности (KPI) DevOps. Такие KPI как частота поставки (deployment frequency), время реализации изменений (change lead time) и среднее время восстановления после инцидента (mean time to recovery) часто улучшаются при внедрении CI/CD с непрерывным тестированием. Однако CI/CD это лишь один из процессов, который может способствовать этим улучшениям. Есть и другие условия для увеличения частоты поставки.

Для начала работы с CI/CD команде разработчиков и эксплуатации необходимо совместно определиться с технологиями, практиками и приоритетами. Команды должны выработать консенсус в отношении правильных подходов к своему бизнесу и технологиям, чтобы после внедрения CI/CD команда постоянно придерживалась выбранных практик.



Краткий обзор инструментов CICD: Gitlab CI, Docker, Ansible


Подробнее..

Добавляем ORM в проект за четыре шага

17.09.2020 00:18:21 | Автор: admin

Представим, что вашему проекту срочно понадобился ORM, и вы хотите внедрить его как можно быстрее. В этой статье я хочу рассказать, как это можно сделать всего за четыре шага на примере использования open source проекта Apache Cayenne.


Для начала вкратце опишу механизм работы с данной библиотекой. Схема базы данных и модели описывается в xml файле, который может быть сгенерирован через GUI приложение или через консоль. Затем на основе xml файла генерируются java объекты, которые являются соответствующим отображением таблиц в базе. Последним шагом создается ServerRuntime объект, который инкапсулирует в себе весь стек Apache Cayenne.
Итак, перейдем к примеру. Что необходимо сделать:


  • Создать схему базы данных
  • Импортировать схему в проект, то есть получить xml файлы с описанием схемы
  • Создать объектную модель, то есть сгенерировать java классы
  • Проинициализировать ServerRuntime для доступа к базе данных из приложения

Что потребуется для начала? Уже существующий maven или gradle проект, Java 1.8+ и база данных. Мой тестовый проект использует maven, java 14 и самую свежую версию Apache Cayenne 4.2.M1. В качестве базы я использую mysql. Вы для своих проектов можете использовать стабильную версию 4.1 и любую из известных реляционных баз на ваш выбор.
Для наглядности я прикреплю ссылку на пример.


Создание схемы


Для примера создадим простейшую схему, состоящую из трех сущностей: марка авто, модель авто, отзыв на модель авто.


CREATE SCHEMA IF NOT EXISTS cars_demo; USE cars_demo;CREATE TABLE car_brand (ID INT NOT NULL AUTO_INCREMENT, NAME VARCHAR(200) NULL, COUNTRY VARCHAR(200) NULL, PRIMARY KEY (ID)) ENGINE=InnoDB;CREATE TABLE car_model (ID INT NOT NULL AUTO_INCREMENT, NAME VARCHAR(200) NULL, CAR_BRAND_ID INT NULL, PRIMARY KEY (ID)) ENGINE=InnoDB;CREATE TABLE feedback (CAR_MODEL_ID INT NULL, ID INT NOT NULL AUTO_INCREMENT, FEEDBACK VARCHAR(200) NULL, PRIMARY KEY (ID)) ENGINE=InnoDB;ALTER TABLE car_model ADD FOREIGN KEY (CAR_BRAND_ID) REFERENCES car_brand (ID) ON DELETE CASCADE;ALTER TABLE feedback ADD FOREIGN KEY (CAR_MODEL_ID) REFERENCES car_model (ID) ON DELETE CASCADE;

Первый шаг пройден, двигаемся ко второму.


Импорт схемы


Здесь уже начинается непосредственное использование библиотеки. Для начала подключим необходимый плагин к проекту:


            <plugin>                <groupId>org.apache.cayenne.plugins</groupId>                <artifactId>cayenne-maven-plugin</artifactId>                <version>${cayenne.version}</version>                <configuration>                    <dataSource> <!--1-->                        <driver>com.mysql.jdbc.Driver</driver>                         <url>jdbc:mysql://127.0.0.1:3306/cars_demo</url>                         <username>root</username>                         <password>root</password>                    </dataSource>                    <cayenneProject>${project.basedir}/src/main/resources/cayenne/cayenne-project.xml</cayenneProject> <!--2-->                    <map>${project.basedir}/src/main/resources/cayenne/datamap.map.xml</map> <!--3-->                    <dbImport> <!--4-->                        <defaultPackage>cayenne.note.project.model</defaultPackage>                        <catalog>cars_demo</catalog>                    </dbImport>                </configuration>                <dependencies>                    <dependency> <!--5-->                        <groupId>mysql</groupId>                        <artifactId>mysql-connector-java</artifactId>                        <version>${mysql.version}</version>                    </dependency>                </dependencies>            </plugin>

  • (1) DataSource, для подключения к базе
  • (2) Путь, где будет лежать сгенерированный xml, который необходим для запуска Cayenne
  • (3) Путь, где будет лежать xml с описанием модели и базы
  • (4) Базовый пакет, где позже будут находиться сгенерированные классы
  • (5) Зависимость от mysql-connector для работы с mysql

Далее в консоли запускаем импорт модели:


mvn cayenne:cdbimport

После выполнения этой команды должны появится два файла, указанные в (2) и (3). Как я уже говорил, файл cayenne-project.xml является служебным файлом, необходимым для работы библиотеки. Файл datamap.map.xml это описание модели базы данных и ее объектного отображения, а также всех связей.


Пару слов о процессе cdbimport: по умолчанию он импортирует всю схему, включая все связи. Данная команда может быть кастомизирована. Вы можете указать, какие сущности стоит включить в импорт, какие исключить, есть возможность указать паттерн для импорта таблиц. Более подробно с этим можно ознакомиться в документации.


Генерация классов


В предыдущем пункте мы сгенерировали описание модели, теперь же нам необходимо сгенерировать java классы, которые можно будет использовать в проекте. Сделать это очень просто, достаточно просто запустить в консоли команду:


mvn cayenne:cgen

После успешной генерации в пакете, который был указан в настройке плагина, будет находиться набор сгенерированных сущностей. Стоит обратить внимание, что сгенерировалось два набора классов. Первый находится в пакете auto и является служебным. Не стоит модифицировать эти классы, так как все изменения исчезнут при следующей генерации. Для пользовательских изменений существуют классы без нижнего подчеркивания, которые наследуются от классов из пакета auto. Именно они предназначаются для прямого использования и кастомизации.


Пример использования


Мы на финишной прямой, осталось только привести пример использования Apache Cayenne.
Создадим ServerRuntime это основной стэк Cayenne, который создается один раз для всего проекта.
Из рантайма всегда можно получить ObjectContext объект, который используется для работы с базой данных.


ServerRuntime cayenneRuntime = ServerRuntime.builder()                .dataSource(DataSourceBuilder                        .url("jdbc:mysql://127.0.0.1:3306/cars_demo")                        .driver("com.mysql.cj.jdbc.Driver")                        .userName("root") // Need to change to your username                        .password("root") // Need to change to your password                        .build())                .addConfig("cayenne/cayenne-project.xml")                .build();        ObjectContext context = cayenneRuntime.newContext();

Создадим несколько сущностей и отправим их в базу:


CarBrand carBrand = context.newObject(CarBrand.class);carBrand.setName("BMW");carBrand.setCountry("Germany");CarModel carModel = context.newObject(CarModel.class);carModel.setName("i3");carModel.setCarBrand(carBrand);Feedback feedback = context.newObject(Feedback.class);feedback.setFeedback("Like");feedback.setCarModel(carModel);context.commitChanges();

Как видно, мы создаем объекты при помощи ObjectContext, затем модифицируем их и фиксируем изменения при помощи context.commitChanges().


Для выборки сущностей можно использовать API на любой вкус от чистого sql и ejbql до хорошо читаемого API. Полное описание можно найти в документации.
Небольшой пример обычного селекта из базы с использованием Apache Cayenne:


List<CarBrand> carBrans = ObjectSelect.query(CarBrand.class).select(context);

На этом у меня все. Как видно из этого примера, за несколько шагов можно получить боевой ORM, который полностью готов к работе. Надеюсь статья оказалась полезной. С полным примером можно ознакомиться здесь.

Подробнее..

Перевод Что такое GitOps? Расширяем DevOps на Kubernetes и дальше

29.10.2020 06:12:20 | Автор: admin

TL;DR: GitOps применяет те же способы для развертывания инфраструктуры, какими пользуются DevOps и CI/CD для развертывания приложений.



За последние десять лет разработка приложений увидела много революционных изменений. Часть их возникла из методов кластеризации вокруг DevOps-подхода и CI/CD. Еще часть таких изменений пришла из движения от монолитной кодовой базы к основанным на облачных технологиях микросервисам, которые запускаются в контейнерах и управляются платформами оркестровки, например Kubernetes.


Основанные на контейнерах приложения запускаются в кластеризированных системах или в облаках, могут быть сложными по структуре и трудными для раскатки и управления даже с использованием оркестраторов. GitOps появился в виде набора методов, цель которых упрощение этой управленческой задачи с использованием подходов, похожих на методы DevOps и CI/CD.


Ключевой идеей GitOps является инфраструктура-как-код, имеющая такой же смысл для создания инфраструктуры, как DevOps для раскатки приложений. Таким образом, не только приложения, но и нижележащие сервера и сети описываются в файлах, которые обрабатываются, как и любой другой код, лежащий в системе контроля версий, с помощью автоматических процессов, совмещающих реальный мир с тем, что написано в этих файлах.


Говоря в терминах GitOps код в системе контроля версий единый истинный источник того, как приложение будет работать в производственном окружении.


Определение GitOps


Компания Weaveworks сделала больше всех для популяризации идеи GitOps. Мы немного погрузимся в роль Weaveworks, и для начала посмотрим на определение GitOps от этой компании, состоящее из двух моментов:


  • Эксплуатационная модель Kubernetes и прочих облачных технологий предоставляет набор передовых методов, соединяющих развертывание, управление и мониторинг контейнеризированных кластеров и приложений.
  • Устоявшийся способ управления приложениями для разработчика, где сквозные конвейеры CI/CD и рабочие процессы Git применяются как для разработки, так и для эксплуатации.

Другими словами, GitOps особый набор методов, разработанный для управления Kubernetes и прочими сходными платформами, который предполагается использовать шире, поскольку все больше и больше компаний-разработчиков принимают DevOps и переносят код в облака. Но чтобы понять секреты GitOps и проблемы, решаемые им, нам нужно обсудить входящие в него компоненты.


Определение Git


Git в GitOps это широко известная распределенная система контроля версий, разработанная Линусом Торвальдсом в 2005 году. Git инструмент, позволяющий командам разработчиков работать совместно над кодовой базой приложения, сохраняя различные ветки кода, над которыми они работают, прежде чем слить их вместе в готовый к промышленному использованию код. Одним из ключевых моментов Git является запрос на слияние, в котором разработчик формально просит добавить код, над которым он работал, в другую ветку кодовой базы. Запрос на слияние в Git дает возможность совместной работы и обсуждения для членов команды. Члены команды должны достичь соглашения по новому коду, который будет добавлен в приложение. Git также сохраняет старые версии кода, что делает возможным легкий откат к последней рабочей версии, если вдруг что-то пойдет не так. Кроме того, можно легко посмотреть различия между версиями. Git также известен как основа GitHub, облачной системы контроля версий, но сам Git программа с открытым исходным кодом, которую можно установить везде, начиная с внутренних серверов компании и заканчивая вашей рабочей машиной.


Обратите внимание: хоть мы обычно представляем Git как инструмент разработки для IT, ему вообще безразлично, какое содержимое хранить. Git прекрасно воспримет любой набор текстовых файлов как вашу кодовую базу, и вы сможете, например, использовать его для писателей, желающих отслеживать правки при совместной работе. Это важно, поскольку большая часть кодовой базы, используемой в качестве основы GitOps, состоит из декларативных файлов настройки, а не исполняемого кода.


Еще одну вещь стоит упомянуть: несмотря на наличии слова "Git" в имени, GitOps в принципе не требует использования Git. Компании, использующие другие системы контроля версий, например Subversion, могут также реализовать GitOps. Но сам Git широко используется в области DevOps для реализации CI/CD, так что большинство проектов GitOps все-таки используют именно Git.


Что такое процесс CI/CD


Полностью описывать CI/CD в этой статье мы не будем, об этом можно почитать например здесь, но нужно сказать пару слов про CI/CD, поскольку это основа работы GitOps. Непрерывная интеграция, первая часть CI/CD, работает с системой контроля версий, например Git: разработчики могут постоянно делать небольшие улучшения их кодовой базы, вместо выкатывания больших монолитных новых версий каждые несколько месяцев или лет. Вторая часть, непрерывная поставка, основана на автоматических системах, т.н. конвейерах, собирающих, тестирующих и выкатывающих новый код для промышленного использования.


Опять же, мы здесь говорим о коде, который все привыкли видеть как код программ, написанный на некотором языке программирования, например C, или Java. Но в GitOps под кодом мы по большей части подразумеваем файлы настроек. Это не просто мелкое примечание это то, на чем основана работа GitOps. Эти файлы, как мы уже говорили, являются единым истинным источником, описывающим, как наша система должна выглядеть. Они по большей части декларативные, а не инструктивные. Это значит, что вместо того, чтобы сказать "запусти десять серверов в файле с настройками, мы просто говорим в системе должно быть десять серверов.


С помощью CI в трактовке GitOps разработчики могут быстро добавить настройки и улучшения в этих файлах, CD начинается там, где автоматизированные программы-агенты делают все необходимое, чтобы реальная версия приложения соответствовала описанию в файлах настройки сходилась с декларативной моделью, если говорить в терминах GitOps.


GitOps и Kubernetes


Как мы уже писали выше, идеи GitOps были сначала обкатаны на приложениях, управляемых Kubernetes. Давайте теперь с тем, что мы знаем о GitOps, вернемся обратно к обсуждению GitOps от Weaveworks, и посмотрим, как они описывают принципы управления обновлениями для Kubernetes, применяемые в GitOps. Кратко процесс работы:


  1. Разработчик делает запрос на слияние с новой функцией;
  2. Код проверяется и одобряется, сливается с кодовой базой;
  3. Слияние активирует конвейер CI/CD, автоматически собирающий, тестирующий и выкатывающий код в registry;
  4. Программный агент получает уведомление об обновлении, скачивает новый код из registry и обновляет файл настроек (написанный на YAML) в репозитории настроек;
  5. Программный агент в кластере Kubernetes определяет, основываясь на файле настроек, что его настройки устарели, скачивает изменения и выкатывает новую функцию.

Weaveworks и GitOps


Очевидно, что шаги 4 и 5 делают большую часть тяжелой работы, ведь программные агенты, волшебным образом синхронизирующие единый истинный источник в репозитории Git с реальным приложением в Kubernetes, делают возможным GitOps. Как мы уже писали, процесс превращения живых систем в те, что описаны в файлах настроек, в терминах GitOps называется схождением. (А когда не синхронизированы расхождением). В идеальном случае схождение может быть достигнуто с помощью автоматизированных процессов, но есть несколько пределов автоматизации. Так что местами потребуется вмешательство человека.


Мы описываем процесс общими словами, но по факту, если вы посмотрите страничку Weaveworks, программные агенты, о которых мы писали, это часть корпоративной платформы Weave Cloud. Термин GitOps придумал генеральный директор Weaveworks, Alexis Richardson, этот термин нужен для того, чтобы привлечь внимание разработчиков, знакомых с DevOps и CI/CD, к платформе Weaveworks.


При этом Weaveworks никогда не заявляла прав на монопольное использование термина GitOps, потому что он больше философия и набор передовых практик, чем некий определенный продукт. В блоге CloudBees, компании, предоставляющей решения CI/CD, есть заметка о том, что GitOps представляет собой открытую, независимую от поставщика модель, разработанную в качестве ответа на управляемые собственнические решения на основе Kubernetes, доступные у всех крупных поставщиков, например Amazon, Google и Microsoft. CloudBees предлагают свое собственное решение GitOps, как и многие другие поставщики в этой отрасли.


GitOps и DevOps


В блоге компании Atlassian, создавшей несколько инструментов для гибких разработчиков, есть объемная, но стоящая вашего времени, статья, описывающая историю и назначение GitOps. По их мнению, GitOps представляет собой логическое продолжение идей, пришедших вместе с DevOps. Согласно описанию, GitOps это развитие идеи инфраструктуры-как-кода, причем сама идея пришла из мира DevOps. GitOps, по мнению Atlassian, закрывает ключевые дыры между нынешними методами DevOps, которые стали решением проблем системного администрирования, и отдельными нуждами распределенных приложений, размещенных в облаках. Автоматическое схождение, предлагаемое разными облачными поставщиками, делает GitOps особенным.


Пока GitOps остается нацеленным на Kubernetes, мы надеемся, что вам стало ясно, как его применять в более широком мире распределенных облачных приложений. Эта статья от поставщика безопасности с открытым исходным кодом выделяет следующие преимущества GitOps:


  • Наблюдаемость: системы GitOps предлагают мониторинг, журналирование, слежение и визуализацию сложных приложений, так что разработчики могут видеть, что и где сломалось;
  • Управление версиями и изменениями: это, очевидно, ключевое преимущество от использования систем контроля версий, например Git. Кривые обновления можно легко откатить;
  • Легкое внедрение: GitOps основан на навыках DevOps, уже имеющихся у большинства разработчиков;
  • Продуктивность: GitOps предлагает увеличение продуктивности, аналогичное получаемому от внедрения DevOps и CI/CD;
  • Проверки: благодаря Git все действия можно отследить до отдельного коммита, делая легким отслеживание исходных причин проблем.

Даже если вы и не используете Kubernetes, есть хорошие шансы на то, что GitOps станет частью вашего рабочего процесса рано или поздно.


От редакции: Практику применения GitOps можно получить на курсе Слёрма CI/CD на примере Gitlab CI. До 3 декабря 2020 курс доступен по цене предзаказа, а также можно стать консультантом-тестером и повлиять на итоговый контент курса.

Подробнее..

Перевод Как архитектура помогает agile-проектам достигать бизнес-целей

13.05.2021 20:21:56 | Автор: admin

Перевод подготовлен в рамках скорого старта курса "Enterprise Architect".

Всех желающих приглашаем на вебинар
Прошлое, настоящее и будущее: роли архитектора предприятия. На этом открытом уроке:
Обсудим роль архитектора предприятия: кем были, кем стали и кем должны быть в обозримом будущем, и почему.
Поговорим о необходимых компетенциях агента изменений и базовых знаниях для позитивного влияния в организации.
Увидим, где начинается архитектурный подход и куда нужно стремиться в профессиональном развитии


Слишком много проектов, инициированных традиционными предприятиями, не могут дать значимых бизнес-результатов в разумные сроки. Проведенный в 2018 году опрос Gartner показал, что 90% руководителей компаний считают цифровые технологии своим главным приоритетом, но при этом 83% руководителей затрудняются добиться значимого прогресса в цифровой трансформации.

Быстрые и постоянные инновационные изменения и более информированные клиенты заставляют компании применять более гибкие бизнес-стратегии. Сроки выполнения теперь короче и требуют, чтобы компании стали более гибкими и научились меньше полагаться на разрозненную организационную структуру для реализации своей стратегии. Капитал необходимо перераспределить на инициативы и проекты, ориентированные на клиентов.

Boston Consulting Group выделяет три основные причины провала крупных инициатив по трансформации бизнеса:

Отсутствие прозрачности. Руководители инициатив или программ трансформации бизнеса не имеют широкого представления о стратегиях фирмы и не могут выделить среди всех своих программ те, которые действительно важны. У них слишком много проектов для выделенных им ресурсов.

Слишком долгие циклы поставки. Традиционные методы управления трансформацией затягивают программы в длительные циклы поставки. Негибкие, многолетние сложные этапы, заложенные на ранних стадиях программ, не подходят для гибких компаний. Целевые бизнес-результаты инициатив цифровой трансформации будут неоднократно меняться в процессе создания гибкого предприятия, ориентированного на потребности клиентов.

Неправильное управление. Высшее руководство должно сопротивляться побуждению делегировать свои ключевые обязанности менеджерам проектов, которые должны нести ответственность за планирование, согласование и разрешение проблем, но обычно не имеют глубокого понимания стратегий развития организации.

Вовлечение enterprise architecture в agile-проекты

Для гибкого управления крупномасштабными инициативами или проектами требуются два важных компонента. Во-первых, необходим структурированный и строгий подход к реализации инициатив по цифровой трансформации от стадии идеи до реализации преимуществ. Выполнение программы никогда не должно начинаться до того, как стратегия будет четко озвучена руководством. Во-вторых, требуется частая перекалибровка плана для адаптации к контекстным изменениям, которые могут произойти во время реализации.

Для реализации этих двух компонентов корпоративные архитекторы (EA) должны участвовать на всех этапах проекта, от стратегического планирования и финансирования до проверок результатов реализации и оценки успеха.

Стратегия и тактика

Большинство компаний создают тщательно продуманные долгосрочные стратегии на высшем уровне управления, но слишком часто им не удается сформулировать соответствующие цели, которые являются более точными и требуют более высокого уровня приверженности. Более того, многие компании могут пересматривать свои стратегии не достаточно часто. Корпоративные архитекторы могут помочь руководству в распространении и более частом преобразовании этих стратегий в тактики на более низких уровнях и по всей горизонтали своей организации. Корпоративные архитекторы также могут помочь руководству в установлении соответствующих реалистичных целей и задач для всех перечисленных стратегий и тактик и могут сыграть важную роль в корректировке целей и бизнес-результатов agile-проектов.

7 преимуществ использования архитектуры в проектах цифровой трансформации

  1. Лучшая согласование ваших agile-проектов со стратегиями и тактиками компании,

  2. Простая идентификация потоков создания ценности и возможностей, которые имеют наибольшее значение и требуют большего финансирования,

  3. Оптимальное планирование и управление производственными мощностями и ресурсами для реализации Agile-проектов,

  4. Лучшее взаимопонимание между agile-командами, чтобы избежать дублирования проектов,

  5. Подробное корпоративное представление для более точного и быстрого определения эпиков и пользовательских историй,

  6. Превосходная вовлеченность сотрудников и

  7. Улучшенная отчетность и аналитика в реальном времени для точной настройки процесса принятия решений.

Финансовая система и определение приоритетов

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

Планирования проекта

Используя элементы своей модели enterprise architecture, корпоративные архитекторы могут ускорить определение требований, эпиков и пользовательских историй, необходимых для поставки и выполнения программ, проектов и спринтов. Кроме того, в крупных agile-программах часто будут дублирующиеся проекты и подпроекты. У корпоративных архитекторов есть необходимый опыт для их обнаружения.

Проверки выполнения проекта

Во время реализации agile-проекта корпоративные архитекторы должны участвовать в регулярных проверках со стороны ключевых членов группы гибкой поставки: продукт менеджеры должны сигнализировать, что следует делать дальше; системные архитекторы должны указать, как можно оптимально реализовать проект; инженерам по выпуску в SAFe необходимо указать лучший способ реализации проекта; а владельцы бизнеса должны стремиться к желаемому бизнес-результату и соответствующей цели, с которой должен быть согласован agile-проект.

Показатели успеха

Ваше недавно разработанное программное обеспечение может отлично работать в соответствии со спецификациями и быть доступным в 99,99% случаев; возможно, вы выполнили свою agile-программу и проекты вовремя и в рамках бюджета. Тем не менее, вы, возможно, не смогли достичь своих бизнес-целей, и соответствующие бизнес-возможности вашего проекта могут по-прежнему работать на слишком низком уровне. В таких случаях корпоративные архитекторы могут помочь выяснить, что пошло не так, и найти соответствующие решения, чтобы это происходило реже.

Архитектура и SAFe

Многие организации на полной скорости продвигаются вперед в своей цифровой трансформации, часто используя SAFe, и обнаруживают, что включение корпоративных архитекторов в их команду увеличивает вероятность достижения бизнес-результатов agile-проектов.

Для поддержки потока создания ценности через SAFeContinuous Delivery Pipeline гибкая архитектура со временем будет развиваться, поддерживая потребности клиентов, пытаясь избежать накладных расходов и задержек, связанных с традиционными методами управления проектами. Гибкая архитектура гарантирует, что система поставки всегда работает, максимально сокращая время на настройку, и поможет внести в поставляемый проект эмерджентный дизайн.

Хорошо скорректированные методы enterprise architecture могут оказаться очень полезными для успеха agile-проектов и повысить вероятность достижения целевых бизнес-результатов организаций, ориентированных на клиентов.

Подробнее о цифровой трансформации:

Также к прочтению:


Узнать подробнее о курсе "Enterprise Architect"

Смотреть вебинар Прошлое, настоящее и будущее: роли архитектора предприятия

Подробнее..

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru