Первое приложение (Avalanche — application framework for Java)
"Avalanche — application framework for Java" — реализация технологии стирающей различия между
вызовами локального и удаленного кода. Отказоустойчивость, масштабируемость,
модифицируемость, непрерывная доступность идут в комплекте приятными бонусами.
Все языки программирования предлагают для начала написать простую программу вывода
сообщения "Hello world". Этот пример не подходит для демонстрации функциональных
возможностей "Avalanche — application framework for Java", так как вызов этого примера всегда
возвращает одну и ту же строку и не позволяет идентифицировать источник, возвративший этот
результат.
Для первого приложения потребуется реализовать два класса (функцию и приложение), один
интерфейс (адаптер функции) и одну JSP страницу для отображения результата. Разработанное
приложение будет выполняться под управлением Tomcat.
Реализация класса функции — DemoFunction
В классе реализации функции нет ничего особенного, это обычный класс Java. В качестве
класса функции может быть использован любой класс. Пусть демонстрационный класс функции
возвращает следующую информацию из операционной системы: PID процесса и имя сервера;
версия операционной системы; название операционной системы.
Код класса DemoFunction.java
package ru.funsys.demo.avalanche;
import java.lang.management.ManagementFactory;
import java.util.Hashtable;
public class DemoFunction {
/**
* Получить информацию из операционной системе.<br>
* <br>
* Из системных свойств выбираются значения<br>
* <b>os.name</b> - имя ОС,<br>
* <b>os.version</b> - версия ОС<br>
* и <b>PID@name</b> - идентификатор процесса и имя сервера
*
* @return именованный список с параметрами ОС
*/
public Hashtable<String, String> getInfo() {
Hashtable<String, String> result = new Hashtable<String, String>();
result.put("os.name", System.getProperty("os.name"));
result.put("os.version", System.getProperty("os.version"));
result.put("PID@name", ManagementFactory.getRuntimeMXBean().getName());
return result;
}
}
Реализация адаптера — DemoAdapter
С точки зрения языка программирования Java, адаптер — это интерфейс, в котором
декларируются методы класса функции, которые планируются вызывать с помощью этого
адаптера. Для класса DemoFunction требуется написать следующий код интерфейса
Код интерфейса DemoAdapter.java
package ru.funsys.demo.avalanche;
import java.util.Hashtable;
import ru.funsys.avalanche.AvalancheRemote;
public interface DemoAdapter {
public Hashtable<String, String> getInfo() throws AvalancheRemote;
}
Следуют отметить, что все методы созданного интерфейса DemoAdapter должны
обязательно содержать декларирование исключения AvalancheException. Данная
реализация чем то напоминает реализацию RMI в языке программирования Java, но есть и
отличия:
- Класс функции (в приведенном примере — DemoFunction) не реализует интерфейс адаптера
(в приведенном примере — DemoAdapter) - В интерфейсе (пример — DemoAdapter) не обязательно нужно определять все публичные
методы класса функции (например, в DemoFunction), достаточно определить только методы,
которого будут вызываться через данный интерфейс.
Реализация адаптера позволяет вызывать методы функции, где бы она не была опубликована.
Реализация класса приложения — DemoApplication
Класс DemoApplication — выполняет вызов метода getInfo() класса DemoFunction
при помощи адаптера DemoAdapter. Пусть класс DemoApplication преобразует
полученный результат вызова getInfo() в формат TXT или HTML.
Код интерфейса DemoApplication.java
package ru.funsys.demo.avalanche;
import java.util.Enumeration;
import java.util.Hashtable;
import ru.funsys.avalanche.Application;
import ru.funsys.avalanche.AvalancheRemote;
public class DemoApplication extends Application {
/**
* Определение поля для хранения экземпляра адаптера
*/
private DemoAdapter info;
/**
* Метод вызова метода адаптера и форматирования полученного результата
* в текстовый формат или формат HTML в зависимости от параметра метода.
*
* @param html true, если необходим формат HTML, иначе false
*
* @return текс или таблицу HTML с параметрами ОС
*/
public String getInfo(boolean html) {
StringBuilder builder = new StringBuilder();
if (html) {
builder.append("<table border=\"1\">");
builder.append("<tr><th>key</th><th>value</th></tr>");
}
try {
// Вызов метода адаптера
Hashtable<String, String> result = info.getInfo();
for (Enumeration<String> enumeration = result.keys(); enumeration.hasMoreElements(); ) {
String key = enumeration.nextElement();
String value = result.get(key);
if (html) {
builder.append("<tr><td>").append(key).append("</td><td>").append(value).append("</td></tr>");
} else {
builder.append(key).append(": ").append(value).append("\r\n");
}
}
} catch (AvalancheRemote e) {
if (html) {
builder.append("<tr><td>").append("error").append("</td><td>").append(e.getLocalizedMessage()).append("</td></tr>");
} else {
builder.append("error").append(": ").append(e.getLocalizedMessage()).append("\r\n");
}
}
if (html) builder.append("</table>");
return builder.toString();
}
}
К классу приложения предъявляются следующие требование: он обязательно должен наследоваться от класса ru.funsys.avalanche.Application.
Поле info определять не обязательно, ссылку на адаптер можно получить по имени, вызвав наследуемый метод getAdapter(String name) класса ru.funsys.avalanche.Application. Имя адаптера задается в конфигурационном файле приложения. Определение поля позволяет сократить объем кодирования.
Реализация JSP страницы — first.jsp
JSP страница отображает результат вызова метода функции в браузере. Сперва получается ссылка на класс DemoApplication и далее вызывается его метод getInfo c параметром true.
<%@ page import="ru.funsys.demo.avalanche.DemoApplication"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Демонстрационное приложение</title>
</head>
<body>
<h1>Демонстрационное приложение</h1>
<jsp:useBean id='DemoApp' scope='application' class='ru.funsys.demo.avalanche.DemoApplication'/>
<%= DemoApp.getInfo(true) %>
<br>
</body>
</html>
Реализация приложения завершена. Теперь нужно определить конфигурацию приложения.
Файл web.xml
В файле web.xml необходимо определить секцию запуска сервлета AvalancheServlet, указав в его параметрах имена конфигурационных файлов приложения и системы логгирования log4j. Сервлет AvalancheServlet инициирует все объекты приложения на основании файла конфигурации avalanche-config.xml.
<?xml version="1.0" encoding="UTF-8"?>
<!--
web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"
-->
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<display-name>Demo Avalanche</display-name>
<description>
Демонстрационное приложение с использованием framework Avalanche
</description>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<servlet>
<display-name>AvalancheServlet</display-name>
<servlet-name>AvalancheServlet</servlet-name>
<servlet-class>ru.funsys.servlet.http.AvalancheServlet</servlet-class>
<init-param>
<param-name>avalanche.config</param-name>
<param-value>${catalina.base}/conf/avalanche-config.xml</param-value>
</init-param>
<init-param>
<param-name>avalanche.log4j</param-name>
<param-value>${catalina.base}/conf/avalanche-log4j.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
</web-app>
Файл конфигурации приложения avalanche-config.xml
Файл конфигурации приложения с локальным вызовом функции имеет следующий вид
<?xml version="1.0" encoding="UTF-8"?>
<avalanche name="Demo Application">
<function class="ru.funsys.demo.avalanche.DemoFunction" name="info-function" description="Сведения об узле системы" />
<application class="ru.funsys.demo.avalanche.DemoApplication" name="DemoApp" >
<adapter class="ru.funsys.demo.avalanche.DemoAdapter" name="info" uri="info-function" />
</application>
</avalanche>
В этом файле определены две секции <function> и <application>. Секция <application> имеет вложенный элемент <adapter>, в котором в атрибуте uri указано имя локальной функции (см. значение атрибута name секции <function>).
Обращаю внимание на значение атрибута name секции <application>, значение этого атрибута DemoApp указывается в атрибуте id для получения ссылки на экземпляр класса DemoApplication в JSP странице.
Удаленный вызов функции DemoFunction
Вызов удаленной функции обычно требует дополнительной специализированной реализации серверной и клиентской части, предварительно выбрав какое то решения из множества существующих технологий, например REST, SOAP или какую то другую.
"Avalanche — application framework for Java" позволяет избежать дополнительного кодирования для вызова методов удаленной функции DemoFunction. Для этого достаточно изменить конфигурацию приложения и опубликовать копию приложения на удаленном сервере.
Необходимо добавить в конфигурационный файл avalanche-config.xml секции:
- <interface>, обеспечивает вызов метод удаленных экземпляров объектов по указанному протоколу
- <connector>, обеспечивает обращение к методам локальных функций с удаленных узлов приложения.
Удаленный вызов по протоколу RMI
Для обеспечения доступа к удаленным объектам по протоколу RMI в файл конфигурации необходимо добавить следующую секцию
<interface name="rmi-interface" uri="rmi://localhost:23000/rmi-connector" />
где:
- localhost определяет адрес удаленного узла
- 23000 определяет порт RMI Remote Server коннектора удаленного узла
- rmi-connector имя коннектора на удаленном узле
На удаленном узле требуется в конфигурационном файле добавить секцию <connector>
<connector class="RMIConnector" name="rmi-connector" port="23000" >
<publish name="info" function="info-function" />
</connector>
где:
- rmi-connector имя коннектора
- 23000 порт RMI Remote Server
- <publish> публикует локальную функцию info-function в коннекторе, опубликованная функция info-function будет известна удаленным узлам под именем info
Удаленный вызов по протоколу HTTP
Для обеспечения доступа к удаленным объектам по протоколу HTTP в файл конфигурации необходимо добавить следующую секцию
<interface name="http-interface" uri="http://localhost:8080/demo/connector/http-connector" />
где:
- localhost определяет адрес удаленного узла
- 8080 определяет порт HTTP Server коннектора удаленного узла
- demo имя контекста удаленного экземпляра приложения
- connector имя сервлета AvalancheServlet
- http-connector имя коннектора на удаленном узле
На удаленном узле требуется в конфигурационном файле добавить секцию <connector>
<connector class="HTTPConnector" name="http-connector" >
<publish name="info" function="info-function" />
</connector>
где:
- http-connector имя коннектора
- <publish> публикует локальную функцию info-function в коннекторе, опубликованная функция info-function будет известна удаленным узлам под именем info
Примечание! Значение HTTP порта не указывается, используется коннектор HTTP сервера (Tomcat).
Дополнительно нужно добавить секции <multipart-config> в конфигурацию сервлета AvalancheServlet и <servlet-mapping> для определения URI этого сервлета в файле web.xml.
Новая редакция файла web.xml
<?xml version="1.0" encoding="UTF-8"?>
<!--
web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"
-->
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<display-name>Demo Avalanche</display-name>
<description>
Демонстрационное приложение с использованием framework Avalanche
</description>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<servlet>
<display-name>AvalancheServlet</display-name>
<servlet-name>AvalancheServlet</servlet-name>
<servlet-class>ru.funsys.servlet.http.AvalancheServlet</servlet-class>
<init-param>
<param-name>avalanche.config</param-name>
<param-value>${catalina.base}/conf/avalanche-config.xml</param-value>
</init-param>
<init-param>
<param-name>avalanche.log4j</param-name>
<param-value>${catalina.base}/conf/avalanche-log4j.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
<multipart-config>
<!-- 50MB max -->
<max-file-size>52428800</max-file-size>
<max-request-size>52428800</max-request-size>
<file-size-threshold>0</file-size-threshold>
</multipart-config>
</servlet>
<servlet-mapping>
<servlet-name>AvalancheServlet</servlet-name>
<url-pattern>/connector/*</url-pattern>
</servlet-mapping>
</web-app>
Чтобы сохранить работоспособность примера локального вызова функции, добавим две копии секции <application> с именами RMIApp и HTTPApp. Атрибуты uri вложенных элементов <adapter> этих секций примут составные значения имя-интерфейса/имя-удаленной функции, т.е. rmi-interface/info и http-interface/info.
Объединенная редакция конфигурационного файла avalanche-config.xml для локального и удаленного вызовов по протоколам RMI и HTTP
<?xml version="1.0" encoding="UTF-8"?>
<avalanche name="Demo Application">
<interface name="rmi-interface" uri="rmi://localhost:23000/rmi-connector" />
<interface name="http-interface" uri="http://localhost:8080/demo/connector/http-connector" />
<function class="ru.funsys.demo.avalanche.DemoFunction" name="info-function" description="Сведения об узле системы" />
<application class="ru.funsys.demo.avalanche.DemoApplication" name="DemoApp" >
<adapter class="ru.funsys.demo.avalanche.DemoAdapter" name="info" uri="info-function" />
</application>
<application class="ru.funsys.demo.avalanche.DemoApplication" name="RMIApp" >
<adapter class="ru.funsys.demo.avalanche.DemoAdapter" name="info" uri="rmi-interface/info" />
</application>
<application class="ru.funsys.demo.avalanche.DemoApplication" name="HTTPApp" >
<adapter class="ru.funsys.demo.avalanche.DemoAdapter" name="info" uri="http-interface/info" />
</application>
<connector class="RMIConnector" name="rmi-connector" port="23000" >
<publish name="info" function="info-function" />
</connector>
<connector class="HTTPConnector" name="http-connector" >
<publish name="info" function="info-function" />
</connector>
</avalanche>
Для сохранения работоспособности JSP страницы first.jsp можно создать ее копии для вызова удаленной функции по протоколу RMI и HTTP, указав значения в атрибуте id RMIApp и HTTPApp соответственно.
Код rmi.jsp
<%@ page import="ru.funsys.demo.avalanche.DemoApplication"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Демонстрационное приложение - RMI</title>
</head>
<body>
<h1>Демонстрационное приложение - RMI</h1>
<p>
Удаленный вызов - протокол RMI
</p>
<jsp:useBean id='RMIApp' scope='application' class='ru.funsys.demo.avalanche.DemoApplication'/>
<%= RMIApp.getInfo(true) %>
</body>
</html>
Код http.jsp
<%@ page import="ru.funsys.demo.avalanche.DemoApplication"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Демонстрационное приложение - HTTP</title>
</head>
<body>
<h1>Демонстрационное приложение - HTTP</h1>
<p>
Удаленный вызов - протокол HTTP
</p>
<jsp:useBean id='HTTPApp' scope='application' class='ru.funsys.demo.avalanche.DemoApplication'/>
<%= HTTPApp.getInfo(true) %>
</body>
</html>
Теперь достаточно скопировать разработанное приложение на другой узел, при необходимости заменить значение localhost на адрес удаленного узла в секциях <interface> файла avalanche-config.xml, и проверить работоспособность приложения.
Как видно из приведенного примера, для обеспечения удаленного вызова функции не потребовалось вносить каких либо корректировок в программный код локального вызова.
Исходные коды, рассмотренного здесь примера приложения, опубликованы на GitHub
Комментарии (304)
lair
25.11.2019 13:35реализация технологии стирающей различия между вызовами локального и удаленного кода.
Никогда такого не было и вот опять?
Признайтесь, как вы решили проблему
обледененияchatty vs chunky?
ne_kotin
25.11.2019 13:37+1Тут упорно избавляются от JSP и сервлет-конфигов последние лет 10, про RMI только в кГовавом энтеГпГайзе помнят.
А тут мало того, что напиши remotable bean, зарегистрируй его в конфиге, так еще и интерфейс ручками там же свяжи.
Ради всего святого — зачем?vl65 Автор
25.11.2019 14:46Жизненный цикл программного обеспечения имеет несколько периодов, самый продолжительный из которых — эксплуатационный. У эксплуатирующей организации возникает много разных непредвиденных ранее требований к программному обеспечению. Файл конфигурации позволяет эксплуатирующей организации самостоятельно реагировать на часть возникающих новых требований.
На мой взгляд, вынос параметров в конфигурационный файл — это «правило хорошего тона».
«Зачем?» — ограничено только вашей фантазией. Допустим, что нужно 100% зарезервировать функционал DemoFunction. Что для этого нужно? Опубликовать DemoFunction на множестве узлов и поменять конфигурацию системы. Все. Допустим, что Вам нужно поймать событие вызова метода getInfo() класса DemoFunction. Создаете «каскадную» функцию, которая вызывает DemoFunction и отдает результат DemoApplication попутно выполнив требуемые Вам действия и меняете конфигурацию. Допустим изменился технологический процесс и часть функций вашей информационной системы потеряла актуальность. Для вывода из эксплуатации этой часть достаточно убрать ее из конфигурации системы.lair
25.11.2019 14:50Допустим изменился технологический процесс и часть функций вашей информационной системы потеряла актуальность. Для вывода из эксплуатации этой часть достаточно убрать ее из конфигурации системы.
И информационная система магически перестанет вызывать эту "часть системы"?
vl65 Автор
25.11.2019 14:53Перестанет и пользователи перестанут видеть эту часть в своем интерфейсе.
lair
25.11.2019 14:57+1Благодаря описанной в посте технологии? Что случится при обращении к
first.jsp
при такой конфигурации?vl65 Автор
25.11.2019 15:22Прошу не путать приложение «Hello world» c промышленным приложением.
lair
25.11.2019 15:33Значит, эта часть мотивации неактуальна.
vl65 Автор
25.11.2019 19:27-1Это уже дело вашей фантазии как Вы реализуете эту функциональность. Например, 2 года назад, в одном из своих приложений подобным образом была отключена часть утратившей актуальность функций, находящееся в эксплуатации с 2007 года. Приложение, при старте "видит" список объектов в своей конфигурации и на основании этого списка строит пользовательский интерфейс. Отключение одного из элементов в конфигурации привело и к изменению в пользовательском интерфейсе, все связанные с этим элементом пункты меню "чудесным образом" пропали.
lair
25.11.2019 20:16+1Это уже дело вашей фантазии как Вы реализуете эту функциональность
… и, возможно, я найду более простой и надежный способ реализовать эту функциональность. Что лишний раз говорит нам, что, может быть, конфиги-то и не так хороши, как кажется?
vl65 Автор
26.11.2019 11:20Использовать для этих целей конфигурацию приложения очень удобно и в первую очередь для эксплуатирующего подразделения! Возникло требование — отключили никого не спрашивая, никому не обращаясь. Возникло требование — подключили. Риск внести ошибку или "сломать" ИС минимальный.
"Удобство эксплуатации" для меня имеет существенно более высокий приоритет чем "удобство реализации" (удобство кодирования для программиста).
lair
26.11.2019 11:27Использовать для этих целей конфигурацию приложения очень удобно
Конфигурацию приложения в общем понимании? Да. Конфигурацию, как вы ее подаете? Не обязательно.
Риск внести ошибку или "сломать" ИС минимальный.
Минимальный из каких вариантов?
vl65 Автор
26.11.2019 14:18Минимальный по сравнению с внесением изменений в ПО
lair
26.11.2019 14:20Я еще раз повторю: внесение изменений в конфигурацию — это и есть внесение изменений в ПО, поэтому ваше противопоставление бессмысленно.
vl65 Автор
26.11.2019 14:30Изменение конфигурации — это не изменение ПО. Конфигурация — переменная составляющая. ПО — неизменная составляющая.
lair
26.11.2019 14:33Изменение конфигурации — это не изменение ПО.
Почему это?
Какая для конечного пользователя разница, что было изменено, если наблюдаемое им поведение программы поменялось?
Представьте на минуту, что речь идет не о компилируемых языках, а о чем-нибудь вроде Python.
vl65 Автор
26.11.2019 14:36Разница огромная! Для изменения конфигурацию достаточно любого текстового редактора. Для приведенного примера достаточно закомментарить или удалить секцию конфигурации. А что нужно для внесения изменений ПО, потрудитесь описать.
lair
26.11.2019 14:40Для изменения конфигурацию достаточно любого текстового редактора.
Я не зря написал про Python. Для внесения изменений достаточно того же самого текстового редактора.
Или вот возьмите AWS Lambda (или API Gateway, не важно): когда я там что-то меняю — это изменение настройки или ПО? И как вы отличаете одно от другого?
Разница огромная!
Напомню вопрос: "Какая для конечного пользователя разница". Разве он вообще видит, каким редактором вы пользовались для внесения изменений?
vl65 Автор
26.11.2019 14:47Не важно, какой язык Вы используете, важно трудаемкость процесса. Сколько строк кода Вам потребуется вычистить в случае отключения какой то части системы? Вы уверены, что сможете сделать это без ошибок? А вам не приходилось слышать, что "этот код написан очень давно и никто толком не помнит как он работает и лучше его не трогать"?
lair
26.11.2019 14:54+1Не важно, какой язык Вы используете, важно трудаемкость процесса.
И почему вы утверждаете, что для конфигурации она меньше?
Сколько строк кода Вам потребуется вычистить в случае отключения какой то части системы?
В правильно спроектированной системе? Одну.
Вы уверены, что сможете сделать это без ошибок?
Нет, конечно. Но и человек, правящий конфигурацию, не может быть в этом уверен.
А вам не приходилось слышать, что "этот код написан очень давно и никто толком не помнит как он работает и лучше его не трогать"?
А вам не приходилось слышать "эта строчка в конфигурации написана очень давно, и лучше ее не трогать"?
vl65 Автор
26.11.2019 15:16-1Конфигурацию может поправить любой специалист.
У Вас такой не найдется
Может. 100% выполнить эту операцию без ошибки.
Не приходилось! А мое утверждение — постоянно, когда речь заходит о какой либо модификации кода находящегося в эксплуатации достаточно долгое время. От разных разработчиков, разных контор.
staticlab
26.11.2019 15:23+2Может. 100% выполнить эту операцию без ошибки.
Человек не может допустить ошибку в конфиге?
lair
26.11.2019 15:23Конфигурацию может поправить любой специалист.
Код может поправить любой специалист.
У Вас такой не найдется
Не найдется чего, простите?
Может. 100% выполнить эту операцию без ошибки.
Если он может, то и я могу. Удалить одну строчку кода — просто.
Не приходилось!
Вам повезло. А мне приходилось, и неоднократно.
vl65 Автор
26.11.2019 15:56В промышленных системах править исходный код, где цена ошибки может принести огромные убытки? Любого просто не подпустят! А править конфиг может (и это его обязанность) администратор системы.
lair
26.11.2019 16:03Вы себе противоречите. Сначала вы говорите, что конфигурацию может поправить любой специалист, потом говорите, что любого не подпустят.
Но в любом случае: в промышленной системе степень ответственности и допуска при правке системы не отличается для кода и конфигурации — что одно, что другое попадает в деплоймент-систему, оттуда выкатывается на стейджинг, оттуда же — на продакшн.
vl65 Автор
26.11.2019 16:09Администратор не программист, в его обязанностях нет пункта править код информационной системы.
lair
26.11.2019 16:15Во-первых, что напишут в обязанности, то и будет.
Во-вторых, править конфигурацию тоже может не входить.
В-третьих, в его обязанности входит удостовериться, что работает, и выкатить, а кто и как внес изменение — не важно.
А главное, все это не имеет никакого отношения к тому, является ли изменение конфигурации изменением ПО.
vl65 Автор
26.11.2019 17:32Наши разные взгляды на обязанности администратора системы выходят за рамки рассматриваемой теме
lair
26.11.2019 17:52И именно поэтому вы не можете использовать "обязанности администратора системы" как аргумент в пользу конфигурации вместо кода.
Что, в свою очередь, снова возвращает нас к утверждению, что и изменение конфигурации, и изменение кода являются изменением ПО (не то что бы обязанности администратора на это как-то влияли).
vl65 Автор
26.11.2019 17:55Моя точка зрения остается неизменной — изменение конфигурации не является изменением ПО. Для меня ваши аргументы не убедительны. Давайте закроем эту тему, она не относится к теме публикации.
lair
26.11.2019 17:57Для меня ваши аргументы не убедительны.
… однако опровергнуть их вам не удалось.
Давайте закроем эту тему, она не относится к теме публикации.
Да нет, напрямую относится. Если из вашего решения выкинуть конфигурацию, что останется?
vl65 Автор
26.11.2019 18:01А Вы доказать вашу правоту не можете. И кто из нас прав?
lair
26.11.2019 18:03Понимаете ли, в чем дело… это вы предлагаете некую технологию, утверждая, что она лучше, удобнее и бла-бла-бла. Вам и доказывать, что это так.
vl65 Автор
26.11.2019 18:05-2Совершенно верно — гораздо лучше и гораздо удобнее. Доказано практикой. Не сталкивались вы с подобными проблемами, не можете осознать преимущества подобного подхода.
lair
26.11.2019 18:18Доказано практикой.
Чьей практикой? Конкретные примеры, исследования, case studies — в студию.
Не сталкивались вы с подобными проблемами
Какими "подобными"?
vl65 Автор
26.11.2019 18:45Чьей практикой?
многолетней практикой эксплуатации распределенных систем
Какими "подобными"?
с проблемами эксплуатации распределенных систем
lair
26.11.2019 18:55многолетней практикой эксплуатации распределенных систем
Я, мне кажется, спрашивал чьей.
с проблемами эксплуатации распределенных систем
Вы этого знать не можете, и, как следствие, ошиблись.
vl65 Автор
26.11.2019 19:12-1ответил ниже
Вы этого знать не можете, и, как следствие, ошиблись.
Тогда странно слышать от Вас некоторые вопросы, при наличии опыта то.
lair
26.11.2019 19:14Тогда странно слышать от Вас некоторые вопросы, при наличии опыта то.
Мне тоже странно слышать ваши утверждения, "при наличии опыта-то". Что лишний раз показывает, что (а) опыт у всех отличается и (б) опыт ничего не гарантирует.
vl65 Автор
26.11.2019 19:19У Вас свое представления — как правильно, у меня — свое. возможно мы оба правы. Но у меня пока нет причин менять свою точку зрения.
lair
26.11.2019 19:23… а у меня нет причин считать, что утверждения, сделанные на основе ваших представлений о правильности, будут применимыми за пределами вашего опыта.
vl65 Автор
26.11.2019 19:07В 2003 году развернул свою первую распределенную систему — реального времени. Масштаб развертывания — вся страна (напомню, у нас много часовых поясов). Система находится в эксплуатации до сих пор. Узлов системы много. С тех пор многократно менялось ПО системы. Происходила миграция узлов на другие аппаратные средства. Узлы меняли свою дислокацию на территории страны. И ни разу не было зафиксировано ни одно сбоя по причини ошибок установки ПО или изменения конфигурации узлов. "Косяки" при обслуживании БД были, проблемы связи — были, внесенные ошибки в отдельную функциональность — были, проблемы со смежными системами, влияющими на работоспособность — были.
lair
26.11.2019 19:14Ну то есть вы опираетесь в качестве доказательства на свою собственную практику?
vl65 Автор
26.11.2019 19:16"опыт ошибок трудных"
lair
26.11.2019 19:21… и вас это не смущает, я понял.
Я вам честно скажу: при выборе между вашим опытом эксплуатации распределенных систем и аналогичным опытом Google я выберу Google.
vl65 Автор
26.11.2019 19:28Существует немало технологий, которые в свое время активно продвигались в том числе лидирующими на рынке IT — компаниями и о которых сейчас ни вспоминает. Так что лидеры IT рынка тоже ошибаются.
lair
26.11.2019 19:30Вы предлагаете мне считать, что вероятность того, что вы ошибаетесь, меньше, чем вероятность того, что — раздельно друг от друга — ошибаются Google и Хамбл/Фарли (ну и, очень скромно, мой опыт тоже)?
ne_kotin
26.11.2019 19:08+2Оч смешно.
Я когда-то в одно щачло поднял интеграционную платформу с таким низким уровнем вхождения, что типовые скрипты служба поддержки клиентов сама разрабатывала и внедряла чуть ли не копипастя с известного. и объем редко превышал сотню строк.
ne_kotin
25.11.2019 16:49+1На мой взгляд, вынос параметров в конфигурационный файл — это «правило хорошего тона».
Параметров — да. А связывание классов — это уже ответственность слоя бизнес-логики. Был бы у вас целевой класс имплементором удаленного интерфейса — можно было бы применять autodiscovery. Постойте-ка… Но это же RMI!
А вы мало того, что RMI переизобретаете (в функциональном смысле), так еще и смешиванием слоев даете возможность разработчику выстрелить себе в ногу.
Не надо так, пожалуйста.vl65 Автор
25.11.2019 17:36При использовании RMI код "привязан" к только к протоколу RMI. В предложенном решении код изолирован от протокола, что позволяет использовать практически любой известный протокол. Эксплуатирующая организация может изменить его в любой момент по своим собственным соображениям. Заметьте, выбор протокола ни как не сказывается на вашем коде. И в этом решении RMI не переизобретен, а, по сути, усовершенствован.
Второе, предложенное решение как раз и раскладывает все "по полочкам". И это называется "модифицируемостью" — простотой модификации промышленной системы. Каждый программный слой выполняет только свою функцию. Бизнес логика постоянно меняется. Предложенное решение позволяет IT подразделению заказчика более гибко реагировать на требование бизнеса, а не ждать "у моря погоды", когда будут выделен бюджет на модификацию ПО для удовлетворения "неожиданно" возникших новых требований или изыскивать другие "обходные" решения, например: — "Вы нам сделаете сейчас, а оплатим мы вам из бюджета следующего года".
lair
25.11.2019 17:44Предложенное решение позволяет IT подразделению заказчика более гибко реагировать на требование бизнеса, а не ждать "у моря погоды", когда будут выделен бюджет на модификацию ПО
Реагировать на требования без модификации ПО? Ну то есть пришел бизнес и говорит "хочу, чтобы курс валют теперь брался из сервиса ЦБРФ, а не вбивался руками", и?..
vl65 Автор
25.11.2019 17:50Пишется новая "функция" и меняется конфигурация системы. Эксплуатируемое ПО не изменяется и, в случае какой либо "неудачи" новой функции, легко может быть возращено в эксплуатацию.
lair
25.11.2019 17:56Во-первых, кто пишет эту новую функцию, если бюджета нет?
Во-вторых, пусть даже ее напишут, как вы замените ручной ввод на регулярную загрузку из внешнего сервиса без соответствующей заранее предусмотренной точки расширения?
А в-третьих, и в самых важных, когда вы говорите "эксплуатируемое ПО не изменяется", вы лукавите. Конфигурация — такая же часть эксплуатируемого ПО, как и код, и изменения в ней должны проходить тот же самый цикл при развертывании; с практической точки зрения нет (не должно быть) разницы, выкатываете вы изменения в коде или изменения в конфигурации.
Проще говоря, нет никакой практической разницы (кроме используемого для изменения набора инструментов) между тем, описаны ваши привязки в конфигурации или в коде.
vl65 Автор
25.11.2019 18:08Функция может быть заказана любому разработчику или быть реализована программистами заказчика, т.е. небольшие изменения можно вносить в рамках текущего бюджета.
"Ручной ввод" он же куда сохраняет результаты свой работы, из конфигурации исключаем функцию "ручного ввода" и включаем функцию "загрузки с сайта" с сохранением "в то же место".
Согласитесь, что процесс изменения конфигурации все же более простоя задача по сравнению изменение программного кода, которое в том числе так же может потребовать и изменения конфигурации.
lair
25.11.2019 18:11+1Функция может быть заказана любому разработчику или быть реализована программистами заказчика, т.е. небольшие изменения можно вносить в рамках текущего бюджета.
Ну так что же мешает внести их прямо в ПО?
"Ручной ввод" он же куда сохраняет результаты свой работы, из конфигурации исключаем функцию "ручного ввода" и включаем функцию "загрузки с сайта" с сохранением "в то же место".
Гм. А как вы из удаленно выполняющейся "функции" получите доступ к "тому же месту"?
(Я даже не спрашиваю, как вы собираетесь вызывать это по расписанию)
Согласитесь, что процесс изменения конфигурации все же более простоя задача по сравнению изменение программного кода
Нет, не соглашусь. Для кода обычно доступно больше средств проверки, чем для конфигурации.
vl65 Автор
25.11.2019 18:34-1А зачем? При вносе изменений прямо в ПО есть риск внести какую то ошибку? Есть. Для изменения ПО необходимо наличие IDE? Необходимо. И т.п. и т.д. Этот процесс гораздо сложнее и "дороже".
Напомню, предложенная технология стирает различия в вызовах локального и удаленного кода. Для этой технологии не имеет значения место исполнения функции. А уж по реализацию шедуллера я вообще молчу. Если лень самому "изобретать", то можно воспользоваться готовым из большого множества OpenSource.
Диагностика все же больше зависит не от средств проверки кода, а от информативности и однозначности сообщений в файлах журналов системы, которые позволяют быстро устанавливать причину ошибки. Мне нравиться информативность и однозначность сообщений в большинства СУБД. В своих системах предпочитаю реализовывать подобный подход.
mayorovp
25.11.2019 20:10+1Вот только при вашем способе есть ещё больше способов внести какую-то ошибку.
lair
25.11.2019 20:15+2При вносе изменений прямо в ПО есть риск внести какую то ошибку? Есть.
… такой же, как при написании "функции" отдельно.
Для изменения ПО необходимо наличие IDE? Необходимо.
… так же, как и для написания "функции" отдельно.
Этот процесс гораздо сложнее и "дороже".
Нет, почему бы? Он точно такой же, как при написании "функции" отдельно.
Единственная разница в том, где вы пишете привязки — в коде или в конфигурации. И я бы не стал утверждать, что в конфигурации это гарантированно проще и дешевле.
Напомню, предложенная технология стирает различия в вызовах локального и удаленного кода. Для этой технологии не имеет значения место исполнения функции.
Это еще надо доказать.
В частности, как вы обеспечите из "функции", выполняемой на другом сервере, доступ к тому же самому хранилищу, что и из "функции", выполняемой локально?
А уж по реализацию шедуллера я вообще молчу.
Нет, ну зачем же. Расскажите нам, как вы добавите функциональность шедулера в приложение, в котором нет соответствующей точки расширения, без его модификации.
Диагностика все же больше зависит не от средств проверки кода, а от информативности и однозначности сообщений в файлах журналов системы, которые позволяют быстро устанавливать причину ошибки.
В смысле — рантайм сообщений? Так это дважды поздно. Меня интересует проверка на этапе разработки, если не получится — на этапе сборки, если и это не получится — на этапе тестирования.
В своих системах предпочитаю реализовывать подобный подход.
… а я в "своих" системах предпочитаю реализовывать подход, при котором максимальное число ошибок обнаруживается до запуска приложения.
staticlab
26.11.2019 15:12А зачем? При вносе изменений прямо в ПО есть риск внести какую то ошибку? Есть. Для изменения ПО необходимо наличие IDE? Необходимо. И т.п. и т.д. Этот процесс гораздо сложнее и "дороже".
Если кто-то опечатается и напишет в вашей конфигурации
<adapter class="ru.funsys.demo.avalanche.DemoAdapterr" name="info" uri="info-function" />
Что произойдёт с системой и когда сотрудник поймёт, что что-то не так?
vl65 Автор
26.11.2019 15:26В логе будет зафиксировано предупреждение
SYS0103W Экземпляр класса "ru.funsys.demo.avalanche.DemoAdapterr" узла <adapter> не создан (класс не найден).
staticlab
26.11.2019 16:25То есть сотруднику, чтобы проверить, не ошибся ли он, нужно будет развернуть всю систему и внимательно прочитать весь лог?
vl65 Автор
26.11.2019 17:16Используемая система логирования достаточно гибкая, можно настроить вывод в отдельный лог для событий отдельного экземпляра объекта (такого решения ни где нет).
Сообщения информативны и однозначны.
В промышленных системах система диагностики "многоярусная", ошибка находиться и устраняется.
staticlab
26.11.2019 17:19+1можно настроить вывод в отдельный лог для событий отдельного экземпляра объекта (такого решения ни где нет)
Какая разница, если можно отфильтровать в Кибане или ещё где-либо?
В промышленных системах система диагностики "многоярусная", ошибка находиться и устраняется.
Тогда вообще никакого преимущества нет.
vl65 Автор
26.11.2019 17:27Преимущества в другом — готовый сервис для создания распределенных масштабируемых систем.
Кстати, сколько бы узлов в распределенной системе не было бы, любая ошибка будет зафиксирована и в вызываемом узле и доставлена и зафиксирована в вызывающий узел. А уж как ей распорядится вызывающий узел — это дело программного кода системы. Анализировать и сопоставлять логи на множестве узлов не нужно.
staticlab
26.11.2019 17:33готовый сервис для создания распределенных масштабируемых систем
Это же был фреймворк, а не сервис.
А написать вызов сервиса с проверкой возвращённой ошибки можно даже на Node.js.
vl65 Автор
26.11.2019 17:50При инициализации приложения на узле системы еще нет ни каких вызовов, нет объекта куда можно возвращать ошибку. Все приложения без исключений в этом состоянии все пишут в лог
lair
26.11.2019 17:55+1Вот только некоторые ошибки можно ловить до инициализации приложения на узле системы. А вы даже не пытаетесь этого делать.
vl65 Автор
26.11.2019 17:59Все без исключения ошибки инициализации ловятся. Если заметили выдается предупреждение, а не сообщение об ошибке. То есть данная вид ошибок классифицирован, как не критическая ошибка и система может далее загружаться.
lair
26.11.2019 18:00Все без исключения ошибки инициализации ловятся.
… на этапе инициализации.
А я говорю про более ранний этап.
vl65 Автор
26.11.2019 18:03-1На каком? На этапе написания кода? Код не изменялся, ловить там нечего!
lair
26.11.2019 18:04На каком?
Написания конфигурации, сборки пакета или развертывания пакета.
vl65 Автор
26.11.2019 18:11Пакет собран и развернут, конфигурация внешний объект по отношению в собранному и развернутому пакету. Тем более речь идет о системе с множеством узлов и у каждого узла может быть собственная индивидуальная конфигурация. ПО везде одинаковое, а конфигурация везде разная. Будете ваши пакеты под каждый узел собирать? А если их 40 штук? А завтра заказчик захочет 1000 иметь? Что будете делать?
lair
26.11.2019 18:20конфигурация внешний объект по отношению в собранному и развернутому пакету.
Это противоречит практикам стабильного развертывания. Вы Хамбла/Фарли не читали?..
Будете ваши пакеты под каждый узел собирать?
Конечно. Это же очень просто.
А если их 40 штук? А завтра заказчик захочет 1000 иметь? Что будете делать?
Версионнику более-менее все равно, хранить один файл конфигурации, 40 или 1000.
Простите за прямой вопрос: а как вы меняете конфигурацию в продакшн-системах?
vl65 Автор
26.11.2019 18:34Это противоречит практикам стабильного развертывания. Вы Хамбла/Фарли не читали?..
В промышленных системах непрерывной доступности не нужно быстрое развертывание. Там нужна плановость и управляемость, а так же свобода действий эксплуатирующей организации, что она по своему усмотрению могла менять конфигурацию исходя из текущих потребностей. Вы же когда меняете конфигурацию СУБД к ее производителю не обращаетесь, чтобы он вам собрал новый пакет СУБД исходя из ваших потребностей.
Простите за прямой вопрос: а как вы меняете конфигурацию в продакшн-системах?
В продакшен, а каких же еще?
lair
26.11.2019 18:43+1В промышленных системах непрерывной доступности не нужно быстрое развертывание.
А я где-то что-то сказал про быстрое развертывание?
Там нужна плановость и управляемость
А чтобы была управляемость, нужна повторяемость, а чтобы была повторяемость, конфигурация должна быть зафиксирована.
Вы же когда меняете конфигурацию СУБД к ее производителю не обращаетесь, чтобы он вам собрал новый пакет СУБД исходя из ваших потребностей.
Нет, я обращаюсь к тому, кто отвечает за развертывание этого участка (это могу быть и я сам), и он собирает новый пакет.
В продакшен, а каких же еще?
Я спросил как вы это делаете. Ну, по шагам, в смысле.
lair
26.11.2019 19:31Так как же вы меняете конфигурацию системы в продакшн?
vl65 Автор
26.11.2019 19:33Да в продакшен, на пассивных узлах — узлах не несущих нагрузки. После внесения изменений в конфигурацию и проверки функционирования узла он возвращается в систему.
lair
26.11.2019 19:35Я уточню еще раз, вдруг я неправильно понял: вы просто меняете (руками, в редакторе или копированием) файлы конфигурации на узлах системы, не несущих нагрузки?
vl65 Автор
26.11.2019 19:37Эту операцию выполняют администраторы, либо они сами знают что хотят изменить, либо выполняю данные рекомендации.
lair
26.11.2019 19:38Но операция все равно та, которую я описал — ручное изменение конфига на узле?
vl65 Автор
26.11.2019 19:41Изменения, как правило не значительные, добавить строчку, удалить строчку или изменить значение атрибута.
lair
26.11.2019 19:42Не важно, какие изменения, просто ответьте на прямой вопрос: да, меняют руками, или нет, меняют как-то иначе?
vl65 Автор
27.11.2019 08:05-1Давно ответил, в любом текстовом редакторе. Да, меняют руками. Я "за" более простые схемы эксплуатации, если можно не использовать в эксплуатации дополнительное ПО, то значит его НЕ НУЖНО использовать. Это понижает требования к сменному персоналу. В критической ситуации какой сотрудник будет ее устранять предсказать невозможно. У сменного персонала сотни разных систем в зоне ответственности.
mayorovp
27.11.2019 09:02+1Подводя итог, я вижу следующее:
- 1000 экземпляров.
- Настраиваются вручную.
- У каждого, потенциально, своя уникальная конфигурация.
И это всё как бы надёжно работает?
Да вас вообще даже близко подпускать к построению архитектуры нельзя!
vl65 Автор
27.11.2019 09:06-1И совершенно не важно, как Вы доставляете конфигурацию до узла системы, Вы ее все равно будете корректировать в ручную — конфигурация каждого узла уникальна.
lair
27.11.2019 10:45Конечно, важно. Во-первых, надо избегать уникальных конфигураций в таких масштабах, во-вторых, даже если все конфигурации уникальны, версионирование и автоматическая доставка дает нам уверенность, что как бы мы не поменяли конфигурацию, мы легко можем ее откатить обратно.
vl65 Автор
27.11.2019 10:46С версионностью нет проблем
lair
27.11.2019 10:47Правда? И как же вы обеспечиваете версионность конфигураций, которые правятся вручную в текстовом редакторе на продакшн-серверах?
vl65 Автор
27.11.2019 10:55Так же как и ваше система версионности, создается копия файла. При желании могут вставляется соответствующий комментарий. Это не существенный вопрос и выходит за рамки темы.
lair
27.11.2019 10:57+2Так же как и ваше система версионности, создается копия файла.
Меня смущает "так же". Я бы понял, если бы вы сказали "файл хранится в системе управления версиями" (хотя тут у меня были бы другие вопросы), но что означает "так же"? Где создается копия файла? Кем? Можно ли изменить конфигурацию, не создавая копию файла.
Это не существенный вопрос и выходит за рамки темы
Это существенный вопрос, потому что он (всегда) является одним из ключевых в дискуссии "конфигурация или код", а это именно то, что мы здесь обсуждаем.
vl65 Автор
27.11.2019 11:06-2Вам остается только поверить мне на слово. Архитектура система разработана так, что хранить копии конфигурационных файлов не нужно — восстановить предыдущую конфигурацию элементарно.
Вы ушли от темы статьи.
lair
27.11.2019 11:09+2Вам остается только поверить мне на слово.
Зачем мне это? Я предпочту работать с решениями, где не надо верить на слово, а все можно проверить.
Архитектура система разработана так, что хранить копии конфигурационных файлов не нужно
Мы говорим про конкретную технологию, предлагаемую вами в статье. И как там это "разработано"?
хранить копии конфигурационных файлов не нужно
Вы только что писали "создается копия файла".
Вы ушли от темы статьи.
Нет. Подавляющая часть статьи о том, как можно прописать привязки в комментариях. Я, как и некоторые другие комментаторы, считаю, что это плохо и неправильно. Следовательно, дискуссия, почему это неправильно — по теме статьи.
vl65 Автор
27.11.2019 11:20При передаче изменений, требующих внесения изменения в конфиг — есть стандартная рекомендация, сделать копию файла. Но если по каким либо причинам она не будет сделана, ни какой трагедии не произойдет. Система в целом останется в рабочем состоянии.
lair
27.11.2019 11:23При передаче изменений, требующих внесения изменения в конфиг — есть стандартная рекомендация, сделать копию файла.
Рекомендация — это то, что люди могут проигнорировать.
Особенно хорошо эта рекомендация сочетается с утверждением "Архитектура система разработана так, что хранить копии конфигурационных файлов не нужно".
Но если по каким либо причинам она не будет сделана, ни какой трагедии не произойдет. Система в целом останется в рабочем состоянии.
В общем случае это утверждение заведомо ложно.
vl65 Автор
27.11.2019 11:26-2жаль. что тут нет смайликов.
Отключение одного узла системы, даже на длительное время — на работоспособности системы не отражается. Не сделали резервной копии и не сделали — нет трагедии.
vl65 Автор
27.11.2019 09:25-2Да вас вообще даже близко подпускать к построению архитектуры нельзя!
Это не Вам судить.
В системе заложены функции самовосстановления после сбоя, система сама справляется со сбойными ситуациями и восстанавливает свою работу, когда это становиться возможным. Система сама принимает решения по переключению на дублирующие узлы.
Так что работает НАДЕЖНО и не требует постоянного "присмотра"
lair
27.11.2019 10:50Это не Вам судить.
Почему, кстати? Вы же судите о том, в чем у меня был опыт или не был? А мы так же можем судить о том, можно ли, по нашему мнению, подпускать вас к проектированию крупных систем. Конечно, никто к этому мнению прислушиваться (или даже выслушивать его) не обязан — до тех пор, пока речь не идет о системах под нашим присмотром — но высказать мы его вполне можем.
lair
27.11.2019 10:43Это, если вкратце, очень плохо. Именно потому, что "у сменного персонала сотни разных систем в зоне ответственности" — вероятность человеческой ошибки увеличивается в разы, особенно когда вы "понижаете требования к сменному персоналу". Намного выгоднее — с точки зрения надежности — уменьшать число требуемого персонала за счет автоматизации, и повышать их квалификацию.
У ручных изменений много недостатков, но два самых важных — это высокая вероятность человеческой ошибки и невозможность автоматического отката в заведомо рабочее состояние.
И да, вернемся к вашему примеру. Вот у вас есть кластер из тысячи узлов (масштабируемость/отказоустойчивость). Вам надо поменять на всем кластере одну настройку. Сколько усилий на это уйдет, и какова вероятность ошибки? А теперь внезапно выяснилось, что настройку менять было не надо, и надо весь кластер откатить обратно. Сколько усилий, какова вероятность ошибки?
vl65 Автор
27.11.2019 10:45-1Сменный персонал не лазит в конфиги от скуки
lair
27.11.2019 10:46А я, вроде бы, и не говорил ничего про скуку. Это рутинная работа по обслуживанию.
vl65 Автор
27.11.2019 10:50Сменный персонал должен иметь возможность внести изменения в конфиг в случае какой то аварии, требующей вмешательства и то, если ему дали такую рекомендацию. ВСЕ! На этом его функции заканчиваются.
lair
27.11.2019 10:54Во-первых, а что тогда с плановыми изменениями?
Во-вторых, опыт показывает, что даже в случае аварии изменения лучше проводить по стандартной процедуре, потому что это упрощает дальнейшие действия.vl65 Автор
27.11.2019 10:57При плановых изменениях все прописано — что делать, как откатывать. С этим нет проблем.
lair
27.11.2019 11:00+2"Все прописано" — это хорошо, но кто это делает?
А если "нет проблем" — то, наверное, нет проблем и ответить на мои комментарии, потому что они в полной мере применимы к плановым обновлениям.
(Удивительно, конечно. Мы занимаемся автоматизацией процессов, потому что машины в среднем лучше следуют инструкциям, нежели люди, но при этом отказываемся видеть, что регламент обновления — это такая же инструкция, которую так же можно автоматизировать.)
vl65 Автор
27.11.2019 11:12Автоматизировать можно все! Лететь на Марс можно хоть сейчас — только сейчас это очень дорого стоить!
Есть экономическая целесообразность. Если текущий процесс не требует затрат, зачем "изобретать велосипед" и вносить в системы еще один узел, который требует опять же какого резервирования, сам подвержен вероятным сбоям и за этим узлом кому то тоже нужно приглядывать?
lair
27.11.2019 11:19только сейчас это очень дорого стоить!
Лететь на Марс, возможно, "очень дорого". Автоматизировать доставку ПО — не очень.
Если текущий процесс не требует затрат, зачем "изобретать велосипед"
Никто не предлагает изобретать велосипед, есть готовые работающие решения.
А зачем? Затем, что вы получаете стабильный и воспроизводимый процесс изменения системы. Вы знаете, в каком состоянии система сейчас, и почему, когда и кем была внесена та или иная настройка.
В каком-то смысле это вопрос того же толка, что и "зачем нужно управление версиями кода". Правда, а зачем?
vl65 Автор
27.11.2019 11:23готовое решение или нет, для системы это "изобретение велосипеда", который "в нужный момент" может оказаться не доступен — сломался, обслуживается, недоступен и т.д.
lair
27.11.2019 11:25+1для системы это "изобретение велосипеда"
Конечно, нет. "Изобретение велосипеда" — это вполне конкретный антипаттерн, подразумевающий повторное придумывание уже существующей функциональности. Я же предлагаю взять готовое.
который "в нужный момент" может оказаться не доступен — сломался, обслуживается, недоступен
С равным успехом в нужный момент может не оказаться доступа к продакшн-серверу.
Я повторю свой вопрос: зачем нужно управление версиями кода? Текущий процесс не требует затрат, в нужный момент система управления версиями (и сборщик) могут оказаться недоступными… зачем?
vl65 Автор
27.11.2019 11:33С точки зрения системы — это именно именно велосипед. При этом — велосипеда, повышающего вероятность отказа системы!
Сравнили тоже версионность кода и конфига! Конфиг в течении жизненного цикла меняется не существенно. Изменения конфига редкая операция и, как правило, меняются какие то значения атрибутов, добавляются или удаляются какие строки.
Изменения исходника может затронуть весь файл. И таких файлов тьма тьмущая. И таких изменений может быть каждый день, несколько раз на дню.
lair
27.11.2019 11:43+1С точки зрения системы — это именно именно велосипед.
Докажите это утверждение.
Конфиг в течении жизненного цикла меняется не существенно.
В течение жизненного цикла чего?
Изменения конфига редкая операция
Это утверждение в общем случае неверно. Особенно оно неверно в контексте предлагаемого вами "не хватает ресурсов — переразвернули на кластере и поправили конфиг".
Изменения исходника может затронуть весь файл. И таких файлов тьма тьмущая. И таких изменений может быть каждый день, несколько раз на дню.
Изменения конфига может затронуть весь файл. И таких конфигов тьма тьмущая. И таких изменений может быть каждый день, несколько раз на дню.
Это, заметим, реальная история из того, чем я занимаюсь прямо сейчас. Того, что вы называете "конфигом", по объему больше, чем программного кода, и меняется оно интенсивнее.
vl65 Автор
27.11.2019 11:53-1Есть одна система многолетней эксплуатации, вы предлагаете другую. Что из этого вытекает? (Оставлю это Вам на размышление.)
"жизненного цикла" эксплуатации системы
Да ежедневно и ежечасно только и вносят изменения в конфиги из "нехватки" ресурсов.
Подражая Вам могу изречь следующее — у Вас плохая система, которая требует каждый раз изменения всего конфига. Теперь понятно, почему Вы постоянно боретесь с "ветряной мельницей"
lair
27.11.2019 11:57Есть одна система многолетней эксплуатации, вы предлагаете другую. Что из этого вытекает?
Что у существующей есть видимые мне недостатки.
"жизненного цикла" эксплуатации системы
В таком случае, это утверждение в общем случае неверно.
Да ежедневно и ежечасно только и вносят изменения в конфиги из "нехватки" ресурсов.
Вы про эластичное масштабирование не слышали?
у Вас плохая система, которая требует каждый раз изменения всего конфига
Вы ничего не знаете про мою систему (что видно из ошибочного суждения "требует каждый раз изменения всего конфига"), поэтому ваше суждение необосновано.
vl65 Автор
27.11.2019 13:44-1Что у существующей есть видимые мне недостатки.
Это ложное утверждение.
В таком случае, это утверждение в общем случае неверно.
Это ложное утверждение.
Вы ничего не знаете про мою систему (что видно из ошибочного суждения "требует каждый раз изменения всего конфига"), поэтому ваше суждение необосновано.
Про то, что Вы написали при обсуждении, у меня сложилось впечатление, что ваша работа "носить воду в ступе".
lair
27.11.2019 13:45Это ложное утверждение.
А теперь докажите это высказывание.
Про то, что Вы написали при обсуждении, у меня сложилось впечатление, что ваша работа "носить воду в ступе".
… ошибочное.
vl65 Автор
27.11.2019 13:49-2Извините, заниматься ежедневной работой изменения множества конфигураций, часть из которой полностью изменяется — робота не создающая полезного продукта.
Это все равно, что художник, который каждый свой день начинает писать одну и ту же картину заново.
Дискуссия на эту тему закрыта.
lair
27.11.2019 13:52Извините, заниматься ежедневной работой изменения множества конфигураций, часть из которой полностью изменяется — робота не создающая полезного продукта.
А заниматься ежедневной работой изменения множества кода, часть из которого полностью изменяется — это работа, создающая полезный продукт?
Это все равно, что художник, который каждый свой день начинает писать одну и ту же картину заново.
Это называется "эскизы".
vl65 Автор
27.11.2019 13:55-1Еще раз — речь идет о конфигурациях системы, а не ее исходных кодах. Если втащили конфигурации в исходные коды — это отвратительное решение
Носите "воду в ступе" и далее. Всего хорошего. Дискуссия закрыта!
lair
27.11.2019 13:57Еще раз — речь идет о конфигурациях системы, а не ее исходных кодах.
Почему ежедневное изменение одного текстового файла — это полезная работа, а другого — нет? На основании какого формального критерия вы проводите это разделение?
vl65 Автор
27.11.2019 14:07Операция изменения конфигурации узла — разовая операция. Она может потребоваться раз в месяц, раз в полгода, раз в год или вообще никогда не потребуется ее выполнять.
Вы занимаетесь ежедневным изменением конфигурации, как я понимаю, в следствии изменения кода — это глупость! И еще утверждаете, что это верх совершенства.
lair
27.11.2019 14:10Операция изменения конфигурации узла — разовая операция. Она может потребоваться раз в месяц, раз в полгода, раз в год или вообще никогда не потребуется ее выполнять.
Операция изменения кода — разовая операция. Она может потребоваться раз в месяц, раз в полгода или вообще никогда не потребуется ее выполнять.
И еще утверждаете, что это верх совершенства.
Нет, не утверждаю (в противном случае вы легко можете найти цитату, где я это утверждаю, не правда ли?)
Но я задал вам вопрос:
почему ежедневное изменение одного текстового файла — это полезная работа, а другого — нет? На основании какого формального критерия вы проводите это разделение?
И вы снова на него не ответили.
vl65 Автор
27.11.2019 14:14-1Не пишите глупости.
lair
27.11.2019 14:15Я их и не пишу, в общем-то (обратное тоже было бы несложно продемонстрировать). Может быть, если ваша же возвращенная вам фраза кажется вам глупостью — что-то не так с вашей фразой?
vl65 Автор
27.11.2019 14:17-2Вы откровенно занимаетесь троллингом. Не надо.
lair
27.11.2019 14:20Отнюдь. Я задаю вопросы, цель которых — продемонстрировать мою точку зрения (на правильный процесс управления конфигурацией и развертыванием, и, как следствие, на архитектуру приложения). А вы от них уходите (вероятно, потому что у вас нет на них удобного вам ответа, но это, конечно, мое допущение).
vl65 Автор
27.11.2019 14:35-2Вы решаете свою частную задачу, возможно думаете, что решаете ее правильно. Ну и решайте ее как Вам угодно.
lair
27.11.2019 14:38+1Ну так и вы в процессе написания своего фреймворка решали свою частную задачу, однако почему-то решили поделиться своим фреймворком с общественностью. Не вижу причин, почему я не могу поделиться с общественностью своими взглядами на архитектурные принципы, заложенные в ваш фреймворк, и их применимость для задач, о которых я что-то знаю.
vl65 Автор
27.11.2019 14:39Ни кто Вам не мешает написать статью и поделиться своим решением. Пишите.
lair
27.11.2019 14:19+1Простой тест, кстати.
Это код или конфигурация? (только сразу объясните, почему)
Текст{ "StartAt": "select-task", "States": { "select-task": { "Type": "Choice", "Choices": [ { "Variable": "$.startAt", "StringEquals": "describe-endpoint", "Next": "describe-endpoint" }, { "Variable": "$.startAt", "StringEquals": "deploy-model", "Next": "deploy-model" } ], "Default": "train" }, "train": { "Type": "Task", "Resource": "arn:aws:states:::sagemaker:createTrainingJob.sync", "Parameters": { "TrainingJobName.$": "$.inputs.TrainingJob.TrainingJobName", "Tags.$": "$.inputs.Tags", "AlgorithmSpecification.$": "$.inputs.TrainingJob.AlgorithmSpecification", "RoleArn.$": "$.inputs.TrainingJob.RoleArn", "ResourceConfig.$": "$.inputs.TrainingJob.ResourceConfig", "HyperParameters.$": "$.inputs.TrainingJob.HyperParameters", "StoppingCondition.$": "$.inputs.TrainingJob.StoppingCondition", "InputDataConfig.$": "$.inputs.TrainingJob.InputDataConfig", "OutputDataConfig.$": "$.inputs.TrainingJob.OutputDataConfig" }, "ResultPath": "$.outputs.TrainingJob", "Next": "deploy-model" }, "deploy-model": { "Type": "Task", "Parameters": { "Model": { "ModelName.$": "$.inputs.Model.ModelName", "Tags.$": "$.inputs.Tags", "ExecutionRoleArn.$": "$.inputs.Model.ExecutionRoleArn", "PrimaryContainer": { "ModelDataUrl.$": "$.outputs.TrainingJob.ModelArtifacts.S3ModelArtifacts", "Environment.$": "$.inputs.Model.Environment", "Image.$": "$.inputs.Model.Image" } }, "EndpointConfig": { "EndpointConfigName.$": "$.inputs.EndpointConfig.EndpointConfigName", "Tags.$": "$.inputs.Tags", "InitialInstanceCount.$": "$.inputs.EndpointConfig.InitialInstanceCount", "InstanceType.$": "$.inputs.EndpointConfig.InstanceType" }, "Endpoint": { "EndpointName.$": "$.inputs.Endpoint.EndpointName", "Tags.$": "$.inputs.Tags" } }, "ResultPath": "$.outputs.Deployment", "Next": "describe-endpoint" }, "describe-endpoint": { "Type": "Task", "Parameters": { "EndpointName.$": "$.outputs.Deployment.Endpoint.EndpointName" }, "ResultPath": "$.Endpoint", "Next": "check-endpoint-status" }, "check-endpoint-status": { "Type": "Choice", "Choices": [ { "Variable": "$.Endpoint.EndpointStatus", "StringEquals": "InService", "Next": "endpoint-deployed" }, { "Or": [ { "Variable": "$.Endpoint.EndpointStatus", "StringEquals": "Creating" }, { "Variable": "$.Endpoint.EndpointStatus", "StringEquals": "Updating" } ], "Next": "wait-check" } ], "Default": "fail" }, "wait-check": { "Type": "Wait", "Seconds": 60, "Next": "describe-endpoint" }, "endpoint-deployed": { "Type": "Succeed" }, "fail": { "Type": "Fail" } } }
vl65 Автор
27.11.2019 14:25-1это некоторый аналог файла pom.xml, используемого maven для сборки проекта. В конфигурации эксплуатируемой системы ни то ни другое не имеет какого либо отношения. Путаете кислое с пресным.
lair
27.11.2019 14:28+1это некоторый аналог файла pom.xml, используемого maven для сборки проекта.
Нет. Ну то есть вообще нет, ни в каком месте. Этот пример не имеет никакого отношения к сборке, и используется в ходе штатной эксплуатации одной из разрабатываемых мной систем.
Так это код или конфигурация?
vl65 Автор
27.11.2019 14:37-2И что, ваша работа и заключается в постоянном и ежедневном изменении этого файла?
lair
27.11.2019 14:39Не ежедневном, а тогда, когда меняется соответствующий процесс. Сейчас вот AWS выкатили multi-model hosting — будем править соответствующим образом.
Но вы так и не ответили на вопрос: это код или конфигурация?
vl65 Автор
27.11.2019 14:40-1не вижу ответа на мой вопрос. Вопрос напомнить?
lair
27.11.2019 14:40Напомните.
vl65 Автор
27.11.2019 14:42-1не проблема
И что, ваша работа и заключается в постоянном и ежедневном изменении этого файла?lair
27.11.2019 14:43Нет, моя работа не заключается в постоянном и ежедневном изменении этого файла.
Ваша очередь: это код или конфигурация?
vl65 Автор
27.11.2019 14:47-1напишите статью
lair
27.11.2019 14:52Ээээ… нет.
Если у вас нет ответа на этот вопрос, мне придется считать, что ваше разделение между кодом и конфигурацией — произвольно (проще говоря, "как мне хочется"), а, следовательно, никакой формальной логики за вашими построениями "конфигурацию надо делать вот так, а не так как код" — просто нет.
vl65 Автор
27.11.2019 14:57-1Ваше решение осуждать бессмысленно, оно здесь не опубликовано. Опубликуйте, по обсуждаем.
lair
27.11.2019 14:58А я не предлагаю обсуждать мое решение, я задаю конкретный вопрос к вашей методологии работы с кодом и конфигурацией: такой файл надо считать кодом или конфигурацией?
lair
27.11.2019 15:02… потому что это вы утверждаете, что изменение конфигурации не является изменением ПО. Вот мне и интересно: изменение этого файла — это изменение ПО, или нет?
vl65 Автор
27.11.2019 15:03-1Хорошо. Тоже конкретный встречный вопрос. Облегчу даже Вам задачу, подскажу, пример из фрагмента кода статьи
/** * Определение поля для хранения экземпляра адаптера */ private DemoAdapter info;
Это про инициализированная переменная или нет?
lair
27.11.2019 15:24Понятия не имею, я не настолько хорошо знаком с терминологией Java.
vl65 Автор
27.11.2019 15:25Мне продублировать ваш ответ на ваш вопрос?
lair
27.11.2019 15:28Откуда ж я знаю, подходит этот ответ к вашей ситуации, или нет?
vl65 Автор
27.11.2019 15:30Ваш ответ на мой вопрос отлично отвечает на ваш вопрос. Дублировать этот ответ, как я понимаю, не надо.
lair
27.11.2019 15:34+1Ага, то есть вы говорите, что вы понятия не имеете, является мой пример кодом или конфигурацией, и вы не настолько знакомы с терминологией Java. Окей, так и запишем (это хорошо сочетается с тем, как вы сначала уверенно отписались, что "это некоторый аналог файла pom.xml").
Отойдем на шаг дальше. Вот у меня есть описание некоего рабочего процесса (workflow), которое никогда не при каких условиях не может быть поправлено конечным пользователем системы. От чего зависит, считать это описание кодом или конфигурацией?
vl65 Автор
27.11.2019 15:37-2Очень не хватает тут смайликов.
Статью в студию.lair
27.11.2019 15:38Повторюсь, смысла в статье нет, мы с простыми вопросами разобраться не можем.
vl65 Автор
27.11.2019 15:40-1Вы задаете вопрос, образно, что в черном ящике.
Мое видение описано в статье, где ваше?
lair
27.11.2019 15:42Вы задаете вопрос, образно, что в черном ящике.
Ну так если вам не хватает информации для ответа на вопрос — вы спросите, я отвечу.
Мое видение описано в статье, где ваше?
В этой цепочке комментариев.
И, кстати, ваше видение того, что считать кодом, а что — конфигурацией, и, что важнее, почему, в статье не описано.
peresada
Не увидел ни одного теста производительности в статье.
vl65 Автор
Тема производительности выходит за рамки «первого приложения». Эту тему планирую раскрыть позднее.
lair
Тогда почему хаб "высокая производительность"?
vl65 Автор
Позволяет строить высокопроизводительные распределенные отказаустойчивые системы непрерывной доступности.
lair
Так это утверждение вроде бы нуждается в доказательстве, разве нет?
vl65 Автор
Нуждается, но это уже выходит за рамки простого приложения.
lair
Значит, в рамках простого приложения этот хаб указан безосновательно.
vl65 Автор
В рамках простого приложения этот хаб относится к фремворку, который позволяет это делать. В отличии от того же REST, SOAP и прочих технологий здесь нет «лишних» преобразований при передаче данных между узлами системы, что при всех прочих равных возможностей будет показывать пусть небольшую, но все же большую производительность.
lair
Это утверждение нуждается в доказательстве.
Поймите: вот я открываю хаб, вижу там вашу статью, захожу в нее — а там про производительность ни одного (полезного) слова.
vl65 Автор
Зачем ходить по кругу, возвращаясь многократно к одному и тому же? Этот вопрос за рамками этой статьи.
lair
Если этот вопрос за рамками этой статьи, то эта статья — за рамками хаба "Высокая производительность". О чем, собственно, я сразу и написал.
vl65 Автор
Рассмотренная технология позволяет создавать приложения высокой производительности, хотя бы тем, что можно добавлять по своему усмотрению неограниченное число узлов. На GitHub (ссылка в конце статьи) опубликован простой пример каскадной функции, которая "распределяет" нагрузку между множеством узлов, с которых вызывается метод getInfo().
DemoCascadeFunction
lair
(а) в статье об этом ни слова
(б) измерения в студию
vl65 Автор
Постараюсь раскрыть эту тему в следующей статье.