Статьи

История ужасов развития — Релиз Кошмар

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

не-случилось-QA

история

Я думаю, что это произошло примерно в 2009 году. Мне и моей команде пришлось поддерживать унаследованное веб-приложение от среднего до большого размера, содержащее около 500 тысяч строк кода. Это приложение было разработано другой компанией, поэтому у нас не было кода. Так как мы отвечали сейчас и нуждались в коде для его обслуживания, они передали нам код в zip-файле (первый указатель на то, что что-то не так)!

Их процесс выпуска был своеобразным, если не сказать больше. Я уверен, что есть худшие процедуры выпуска. Этот состоял в копировании измененных файлов (* .class, * .jsp, * .html и т. Д.) В развернутую военную папку на сервере Tomcat. У нас также было три среды (QA, PRE, PROD) с разными версиями приложений, и мы не знали, какие файлы были развернуты в каждой. У них также было приложение для управления билетами с прикрепленными скомпилированными файлами, готовыми к развертыванию и не имеющими представления об оригинальных источниках. Что здесь может пойти не так?

Проблема

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

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

Причина

Проблема не была точно связана с измененным кодом. Посмотрите на следующие файлы:

BatchConfiguration

1
2
3
public class BatchConfiguration {
    public static final String OS = "Windows";
}

И:

01
02
03
04
05
06
07
08
09
10
11
12
13
public class BatchProcess {
    public void copyFile() {
        if (BatchConfiguration.OS.equals("Windows")) {
            System.out.println("Windows");
        } else if (BatchConfiguration.OS.equals("Unix")) {
            System.out.println("Unix");
        }
    }
 
    public static void main(String[] args) {
        new BatchProcess().copyFile();
    }
}

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

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

В любом случае, разработчик изменил переменную на Windows чтобы он мог продолжить некоторые тесты. Все было хорошо, поэтому он выполняет релиз. Он скопировал полученный BatchProcess.class на сервер. Он не беспокоился о BatchConfiguration , так как на сервере был настроен Unix верно?

Может быть, вы уже заметили проблему. Если нет, попробуйте следующее:

  • Скопируйте и постройте код.
  • Выполните это. Проверьте вывод, вы должны получить Windows .
  • Скопируйте полученный BatchProcess.class в пустой каталог.
  • Выполните это снова. Используйте командную строку java BatchProcess

Что произошло? У вас есть выход Windows , верно? Подождите! У нас не было файла BatchConfiguration.class в каталоге выполнения. Как это возможно? Разве нам не нужен этот файл там? Разве мы не должны получить ошибку?

Когда вы создаете код, компилятор Java BatchConfiguration.OS переменную BatchConfiguration.OS . Это означает, что компилятор заменит выражение переменной в операторе if фактическим значением переменной. Это как if ("Windows".equals("Windows"))

Попробуйте выполнить javap -c BatchProcess . Это покажет вам представление байт-кода файла класса:

BatchProcess.class

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
public void copyFile();
    Code:
       0: ldc           #3                  // String Windows
       2: ldc           #3                  // String Windows
       4: invokevirtual #4                  // Method java/lang/String.equals:(Ljava/lang/Object;)Z
       7: ifeq          21
      10: getstatic     #5                  // Field java/lang/System.out:Ljava/io/PrintStream;
      13: ldc           #3                  // String Windows
      15: invokevirtual #6                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
      18: goto          39
      21: ldc           #3                  // String Windows
      23: ldc           #7                  // String Unix
      25: invokevirtual #4                  // Method java/lang/String.equals:(Ljava/lang/Object;)Z
      28: ifeq          39
      31: getstatic     #5                  // Field java/lang/System.out:Ljava/io/PrintStream;
      34: ldc           #7                  // String Unix
      36: invokevirtual #6                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
      39: return

Вы можете подтвердить, что все переменные заменены их постоянными значениями.

Теперь вернемся к нашей проблеме. В файле .class, скопированном на серверы PROD, было установлено значение Windows . Это испортило все во время выполнения, которое обрабатывало входные файлы с финансовыми данными. Это было причиной проблем, которые я описал ранее.

отава

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

Да, мы перенесли код в нечто управляемое. Это теперь на VCS с тегом для каждого выпуска и версии.

Ссылка: История ужасов разработки — Выпустите Nightmare от нашего партнера JCG Роберто Кортеса в блоге