В нашей реальной работе, когда мы сталкиваемся с обратной связью от других людей о том, что код работает неправильно, как нам убедиться, что возвращаемые данные неверны?
После того как приложение работает в течение некоторого времени, наша первая реакция — убедиться, можем ли мы воспроизвести проблему? Если мы можем воспроизвести её, то правильно ли мы вызываем метод? Если мы уверены, что вызов метода правильный, то проблема должна быть в параметрах запроса!!! Если параметры запроса всё ещё не являются проблемой, то, чёрт возьми, возможно, действительно есть ошибка, и что нам тогда делать?
Далее, обычный подход заключается в том, чтобы воспроизвести ситуацию в тестовой среде. Если мы можем это сделать, то мы запускаем отладку (или удалённую отладку), строка за строкой, и мы верим, что скоро сможем решить проблему;
Но самое страшное — это «но», тестовая среда не может воспроизвести проблему, а проблема возникает только в рабочей среде, так что же нам делать?
Другой сценарий заключается в том, что для повышения производительности службы кэширование широко используется между различными системами; если есть кэширование, то могут возникнуть проблемы с несогласованностью кэша. Если кэш использует внешние сервисы, такие как Redis или Memcache, то запрос и исправление данных кэша относительно просты; однако, если мы используем память в качестве кэша данных, например, HashMap или Guava, то как мы можем работать с данными в этой памяти? Как мы можем изменить данные в этой памяти?
Из двух сценариев, описанных выше, можно выделить две основные проблемы:
Что нам нужно сделать, чтобы решить две проблемы, описанные выше?
Как получить доступ к методам и данным приложения? Первое, что приходит на ум, — это рефлексия. Нетрудно выполнить определённый метод экземпляра или получить значение свойства экземпляра с помощью рефлексии, но трудно сделать это ненавязчиво, обеспечить связь с внешним миром и сделать его универсальным.
Прежде всего, нам нужно внедрить EndPoint для реализации связи с внешним миром. Это является основным условием для начала работы. EndPoint компонента Fixer отвечает за приём внешних запросов и пересылку их внутреннему анализатору для выполнения доступа к внутренним службам приложения и вывода результатов внешнему пользователю.
На приведённом выше рисунке показана структура проектирования EndPoint. Поскольку современные Java-приложения редко запускаются напрямую в виде jar-файлов, более распространённым способом является запуск служб в других контейнерах, таких как Tomcat, Spring и т.д. Различные контейнеры предоставляют разные способы предоставления услуг. Как мы можем обеспечить элегантную поддержку в различных контейнерах?
После получения запроса внутри приложения сначала необходимо определить местоположение службы, к которой осуществляется доступ, а затем выполнить вызов службы. Процесс реализации выглядит следующим образом:
Исходя из структуры проектирования, давайте найдём ключевые моменты реализации этого проекта.
Обычно, как определить местоположение требуемого метода службы для выполнения на основе переданных параметров запроса? Службы, предоставляемые приложением, обычно делятся на два типа:
Наша основная цель должна быть сосредоточена на первом методе. Получение ServiceHolder для разных способов применения неодинаково, и требовать от нас поддержки всех вариантов непрактично. Поэтому нам нужен механизм, позволяющий пользователям выбирать конкретный метод сервиса на основе ServiceHolder в их приложении.
Это может быть достигнуто с помощью механизма SPI.
Обеспечение взаимодействия с внешним миром, наиболее распространённым решением является предоставление HTTP-интерфейса для приёма внешних запросов. А как насчёт не-web сервисов? Мы также можем открыть сокет для TCP-коммуникации. Тогда возникает вопрос:
Поэтому при конкретной реализации нам необходимо учитывать следующие моменты:
При конкретной реализации будут использоваться следующие механизмы:
От проектирования до реализации, следующие статьи подробно описывают:
Техническая документация
190102-Quick-Fix Создание инструмента для исправления сервисов/данных внутри приложения с нуля
[2019/03/17 190317-Quick-Fix Использование
190104-Quick-Fix Руководство по использованию чистого Jar-приложения и расширения
Сначала добавьте репозиторий, есть два способа: один — это использование версии release на GitHub, преимущество заключается в стабильности; убедитесь, что проблема с обновлением решена;
<repositories>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
</repositories>
Другой способ — использовать мой личный репозиторий
<repositories>
<repository>
<id>yihui-maven-repo</id>
<url>https://raw.githubusercontent.com/liuyueyi/maven-repository/master/repository</url>
</repository>
</repositories>
В зависимости от фактического сценария приложения импортируйте соответствующий пакет зависимостей,
<dependency>
<groupId>com.git.hui.fix</groupId>
<artifactId>fix-core</artifactId>
<version>1.4.2</version>
</dependency>
Примечание:
-Dquick.fix.port
;FixEngine.instance();
для инициализации при входе в приложение;Используйте следующим образом:
curl -X POST -H "Content-Type:application/json" http://127.0.0.1:9999/fixer/call -d '{"service": "CalculateServer", "method": "getCache", "params": ["init"], "type":"static"}'
Пример demo: jar-example (examples/jar-example)
Если у меня чистое Spring-приложение и я не использую SpringMVC, я могу импортировать
<dependency>
<groupId>com.git.hui.fix</groupId>
<artifactId>spring-fixer</artifactId>
<version>1.4.2</version>
</dependency>
Примечание: spring-fixer предоставляет способ доступа к bean-компонентам в контейнере Spring, поэтому, помимо получения статического класса по умолчанию, вы также можете получить доступ к bean-компоненту;
-Dquick.fix.port
;FixEngine.instance()
;Используйте следующим образом:
# Выполнение метода определенного bean
curl -X POST -H "Content-Type:application/json" http://127.0.0.1:8080/inject-fixer-endpoint/call -d '{"service": "demoBean", "method": "randName"}'
# Просмотр значения свойства bean
curl -X POST -H "Content-Type:application/json" http://127.0.0.1:8080/inject-fixer-endpoint/call -d '{"service": "demoBean", "field": "name"}'
# Выполнение метода свойства bean
curl -X POST -H "Content-Type:application/json" http://127.0.0.1:8080/inject-fixer-endpoint/call -d '{"service": "demoBean", "field": "values", "method":"add", "params": ["autoInsertByQuickFixer!"]}'
# Тестирование вызова метода статического члена статического класса
curl -X POST -H "Content-Type:application/json" http://127.0.0.1:9999/fixer/call -d '{"service": "com.git.hui.fix.example.spring.server.StaticBean", "method": "getCache", "params": ["init"], "type":"static"}'
# Пример использования одноэлементного класса
curl -X POST -H "Content-Type:application/json" http://127.0.0.1:8080/inject-fixer-endpoint/call -d '{"service": "SingletonBean", "method": "getInstance", "secondMethod": "sayHello", "secondParams": ["init"], "type":"static"}'
Пример демо: spring-example (examples/spring-example)
Если это SpringMVC-приложение, вы можете импортировать
<dependency>
<groupId>com.git.hui.fix</groupId>
<artifactId>spring-mvc-fixer</artifactId>
<version>1.4.2</version>
</dependency>
Использование: используйте http-сервис, предоставляемый самим mvc, доступ осуществляется по пути /inject-fixer-endpoint/call
, поэтому необходима проверка безопасности.
Используйте так же, как и предыдущие классы. Пример демо: spring-mvc-example (examples/spring-mvc-example)
Если это приложение SpringCloud и вы включили мониторинг приложений actuator, вы можете импортировать
<dependency>
<groupId>com.git.hui.fix</groupId>
<artifactId>spring-cloud-fixer</artifactId>
<version>1.4.2</version>
</dependency>
Использование: интегрируйте FixEndPoint с Actuator в SpringCloud, поэтому при фактическом использовании вам необходимо включить его в конфигурации и установить параметр management.endpoints.web.exposure.include
. Доступ осуществляется по пути: /actuator/inject-fixer-endpoint/call
, где путь actuator
совпадает с путем конфигурации мониторинга приложений.
Используйте таким же образом, как и в предыдущих классах. Пример демо: spring-cloud-example (examples/spring-cloud-example)
v1.1
v1.2 Поддержка указания приоритета ServerLoader
Версия 1.3
Версия 1.4
IArgParser
.Версия 1.4.1
HttpMessageParser
в разных средах.Версия 1.4.2
Отказаться от использования одного компьютера, приветствуется start или добавление друзей для поддержки.
Лучше не верить книге, а полагаться на то, что уже написано. Поскольку мои личные способности ограничены, возможно, есть упущения и ошибки. Если вы обнаружите ошибку или у вас есть лучшее предложение, пожалуйста, критикуйте и исправляйте. Буду благодарен.
Публичный аккаунт и блог.
Код вознаграждения
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Комментарии ( 0 )