Эта статья представляет собой заметку из видеоконспекта некой сети курсов по микросервисам SpringCloud, в которой участвуют
- Конфигурация сервера Eureka и клиента Eureka
- Высокая доступность сервера Eureka
- Два способа межсервисного взаимодействия: RestTemplate и Feign
- Установка и использование RabbitMQ
- Использование центра конфигурации
- Использование Spring Cloud Stream
- Различные варианты использования сервисного шлюза Zuul
Потому что это тест на ноты, напишите немного случайно, Bigwigs прости меня ~
Большинство технологий, упомянутых в этой статье, будут использоваться в одном из моих проектов с открытым исходным кодом.Основная часть бизнес-логики этого проекта в основном написана, и необходимы только проверка авторизации, настройка шлюза и пост-оптимизация. кому интересно может посмотреть..
адрес проекта:GitHub.com/cache Cats/ из…
1. О командной строке
Запустите проект SpringBoot
java -jar test.jar
Запустите проект SpringBoot и укажите порт
java -jar -Dserver.port=8899 test.jar
Начните проект Sprilboot и укажите фон для запуска
nohup java -jar test.jar > /dev/null 2>&1 &
Посмотреть прогресс
ps -ef | grep eureka
убить процесс
kill -9 进程号
Установите проект локально в локальный репозиторий maven.
mvn -Dmaven.test.skip=true -U clean install
2. Сервер Эврика
2.1 Новый
Выберите CloudDiscovery -> Eureka Server.
Обратите внимание на версию SpringBoot
2.2 Конфигурация
Аннотировать приложение класса запуска
@EnableEurekaServer
в файле конфигурацииapplication.yml
регистрационная служба
eureka:
client:
service-url:
defaultZone: http://localhost:8080/eureka/
Запустите проект и введите адрес в браузереhttp://localhost:8080
Вы можете увидеть, что проект запускается нормально и зарегистрироваться самостоятельно.
ApplicationName
даUNKNOWN
, если вы хотите изменить имя приложения, перейдите кapplication.yml
Выполните следующую настройку
eureka:
client:
service-url:
defaultZone: http://localhost:8080/eureka/
spring:
application:
name: eureka
Перезапустите проект, просмотрите его в браузере, имя отображается корректно
Если вы не хотите, чтобы реестр отображался в списке регистрации, настройтеregister-with-eureka: false
eureka:
client:
service-url:
defaultZone: http://localhost:8080/eureka/ #配置默认注册地址
register-with-eureka: false #不让该服务显示在应用列表中
spring:
application:
name: eureka #配置应用名字
3. Клиент Эврика
3.1 Новый проект
Выберите CloudDiscovery -> Eureka Discovery.
Обратите внимание, что версии SpringBoot и SpringCloud такие же, как и у сервера
3.2 Конфигурация
- Вход
Application
добавить аннотацию@EnableDiscoveryClient
@SpringBootApplication
@EnableDiscoveryClient
public class ClientApplication {
public static void main(String[] args) {
SpringApplication.run(ClientApplication.class, args);
}
}
- Настроить адрес сервера
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
spring:
application:
name: client
- Настройте адрес ссылки. После настройки адрес браузера станет
http://clientname:8080/
eureka:
instance:
hostname: clientName
- Если вы часто перезапускаете клиентскую службу, у вас будет следующее предупреждение
Это механизм самозащиты SpringCloud, то есть независимо от того, онлайн сервис или нет, он считается онлайн. В среде разработки эту функцию можно отключить для удобства отладки, обратите внимание, что рабочая среда должна быть включена.
на сервереapplicaitono.yml
Выполните следующую настройку в
eureka:
server:
enable-self-preservation: false
4. Высокая доступность сервера Eureka
В настоящее время клиент зарегистрирован на сервере Eureka, что делать, если сервер зависает?
Несколько серверов Eureka могут быть запущены и зарегистрированы друг с другом.
Здесь презентация запускает три сервера EUREKA для регистрации друг друга и регистрации клиента на этих трех серверах соответственно.
настроить сервер
Старт на трех портах 8761, 8762, 8763 соответственноEurekaApplication
,EurekaApplication2
,EurekaApplication3
три службы, в трех службахapplicaiton.yml
Адреса двух других сервисов настраиваются отдельно.
какEurekaApplication
достойныйhttp://localhost:8762/eureka/,http://localhost:8763/eureka/
,
EurekaApplication2
достойныйhttp://localhost:8761/eureka/,http://localhost:8763/eureka/
,
EurekaApplication3
достойныйhttp://localhost:8761/eureka/,http://localhost:8762/eureka/
,
EurekaApplication
изapplicaiton.yml
следующее:
eureka:
client:
service-url:
defaultZone: http://localhost:8762/eureka/,http://localhost:8763/eureka/
Это связывает три службы друг с другом.
настроить клиент
Затем в клиентеapplicaiton.yml
Сопоставьте все три служебных адреса в
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/,http://localhost:8762/eureka/,http://localhost:8763/eureka/
ПроверятьEurekaApplication
, найдено зарегистрированным на 8762 и 8763. Пока один из трех серверов жив, сервис не зависнет.
5. Связь между приложениями
Существует два основных типа связи между приложениями:
HTTP означает: SpringCloud
RPC расшифровывается как: Дуббо
Два спокойных метода вызова между сервисами в SpringCloud
- RestTemplate
- Feign
5.1 Метод RestTemplate
Существует три метода вызова RestTemplate, которые описаны ниже.
В приложении для записи данных для предоставления контроллера открытых интерфейсов, называемыхServerController
Бар
@RestController
@RequestMapping("/product")
public class ServerController {
@GetMapping("/msg")
public String getMsg(){
return "I am product msg";
}
}
Затем напишите контроллер в приложении, которое должно получать данные, называемоеClientController
5.1.1 Метод 1
Использовать напрямуюRestTemplate
Вручную напишите URL-адрес, который предоставляет данные
@RestController
@RequestMapping("/order")
@Slf4j
public class ClientController {
@GetMapping("/getmsg")
public String getMsg(){
RestTemplate restTemplate = new RestTemplate();
String result = restTemplate.getForObject("http://localhost:8080/product/msg", String.class);
log.info("result={}", result);
return result;
}
}
5.1.2 Метод 2
Вместо того, чтобы вручную вводить URL-адрес, используйтеLoadBalancerClient
Динамически получить по имени приложения, а затем использоватьRestTemplate
.
loadBalancerClient.choose("product");
этоproduct
это идентификатор приложения, которое предоставило данные
@RestController
@RequestMapping("/order")
@Slf4j
public class ClientController {
@Autowired
LoadBalancerClient loadBalancerClient;
@GetMapping("/getmsg")
public String getMsg(){
ServiceInstance serviceInstance = loadBalancerClient.choose("product");
String url = String.format("http://%s:%s/product/msg", serviceInstance.getHost(), serviceInstance.getPort());
RestTemplate restTemplate = new RestTemplate();
String result = restTemplate.getForObject(url, String.class);
return result;
}
}
5.1.3 Метод 3
использовать@LoadBalanced
аннотация
новыйRestTemplateConfig
своего рода
@Component
public class RestTemplateConfig {
@Bean
@LoadBalanced
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
затем вClientController
используется в.
restTemplate.getForObject("http://product/product/msg", String.class);
два в адресеproduct
, первое — это имя приложения, а второе — адрес API. если адрес API/abc
, тогда URL-адресhttp://product/abc
@RestController
@RequestMapping("/order")
@Slf4j
public class ClientController {
@Autowired
RestTemplate restTemplate;
@GetMapping("/getmsg")
public String getMsg(){
String result = restTemplate.getForObject("http://product/product/msg", String.class);
return result;
}
}
5.2 Метод действительности
Есть несколько шагов использования FeiGn
Шаг 1. Внедрение зависимостей
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
Уведомление
Обратите внимание на проблему здесь Зависимости, упомянутые в некоторых видео и статьях,spring-cloud-starter-feign
, я тоже это приводил в начале, но жизнь и смерть не привносишь. Затем перейдите в репозиторий mavenmvnrepository.com/смотри, ищиspring-cloud-starter-feign
Смотри, там написано:
Spring Cloud Starter Feign (deprecated, please use spring-cloud-starter-openfeign)
Сказатьspring-cloud-starter-feign
Устарело, пожалуйста, используйтеspring-cloud-starter-openfeign
.
Версия SpringCloud, которую я использую, относительно высока и может не поддерживаться.spring-cloud-starter-feign
.
Шаг 2. Настройте аннотацию @EnableFeignClients
Конфигурация в начальном классе программы@EnableFeignClients
аннотация
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class OrderApplication {
public static void main(String[] args) {
SpringApplication.run(OrderApplication.class, args);
}
}
не могу найти@EnableFeignClients
Если да, проверьте, правильно ли процитированы зависимости и верна ли версия.
Шаг 3: Создайте инкапсулированный интерфейс
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;
@FeignClient(name = "product")
@Component
public interface ProductClient {
@GetMapping("/product/msg")
String getMsg();
}
добавить в интерфейс@FeignClient
Примечания в скобкахname = "product"
заявляет, что приложение с именемproduct
Приложение находит данные (имя приложения не чувствительно к регистру).
@GetMapping("/product/msg")
Обратите внимание на метод запроса и путь.
такgetMsg()
метод означает запросproduct
API в приложении есть/product/msg
Нить.
Шаг 4: звонок
@RestController
@RequestMapping("/order")
@Slf4j
public class ClientController {
@Autowired
ProductClient productClient;
@GetMapping("/getmsg")
public String getMsg(){
return productClient.getMsg();
}
}
Внедрить созданный на третьем шагеProductClient
, а затем напрямую вызвать метод, определенный в интерфейсе.
я ввожу здесьProductClient
Редактор сообщит об ошибке, но на компиляцию это не повлияет.
Could not autowire. No beans of 'ProductClient' type found
Это не радует глазProductClient
добавил@Component
аннотация.
Наконец, резюмируйте Feign:
- Декларативный клиент REST (псевдо-RPC)
- аннотации на основе интерфейса
6. Установите RabbitMQ
В этой статье для установки RabbitMQ используется Docker, см. руководство по Docker.здесь
Откройте официальную страницу загрузки RabbitMQ.woohoo.rabbitcurrent.com/download.contract… Docker
нажмитеDocker image
Ссылка на страницу с подробностями
Вы можете видеть, что последняя версия3.7.7
,копировать3.7.7-management
, введите следующий код в командной строке и запустите
docker run -d --hostname my-rabbit -p 5672:5672 -p 15672:15672 rabbitmq:3.7.7-management
Используйте docker ps, чтобы увидеть наши запущенные контейнеры
Solo-mac:~ solo$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
345859e88ead rabbitmq:3.7.7-management "docker-entrypoint.s…" 2 minutes ago Up 2 minutes 4369/tcp, 5671/tcp, 0.0.0.0:5672->5672/tcp, 15671/tcp, 25672/tcp, 0.0.0.0:15672->15672/tcp goofy_volhard
Вход через браузерhttp://localhost:15672
Open Rabbitmq, в первый раз потеряет имя пользователя и пароль, имя пользователя и парольguest
, войдите в интерфейс управления после ввода
На этом установка RabbitMQ завершена.
7. Центр конфигурации
7.1 Конфигурация сервера центра конфигурации
-
Новая конфигурация проекта
勾选 Cloud Config -> Config Server 和 Cloud Discovery -> Eureka Discovery
-
Добавить аннотацию к классу запуска
@SpringBootApplication @EnableDiscoveryClient @EnableConfigServer public class ConfigApplication { public static void main(String[] args) { SpringApplication.run(ConfigApplication.class, args); } }
-
Создайте новый проект на github или в облаке кода,
order
Проектapplication.yml
Файл конфигурации загружен для тестирования. -
настроить проект
application.yml
документeureka: client: service-url: defaultZone: http://localhost:8761/eureka/ server: port: 8081 spring: application: name: config cloud: config: server: git: uri: https://gitee.com/xxxxxxx username: xxxxxx password: xxxxxx basedir: xxxxxx #本地的路径
uri — адрес склада, логин и пароль — логин и пароль склада
-
После завершения настройки запустите проект, вы увидите, что проект зарегистрирован в центре регистрации, и получите доступ к нему в браузере.
http://localhost:8081/order-a.yml
Также прочитайте файл конфигурации на git в обычном режиме.Суффикс ввода адреса доступа — «/order-a.yml», который объясняется здесь.
/{name}-{profiles}.yml /{label}/{name}-{profiles}.yml name: 服务名,这里是 order profiles 环境 label 分支(branch) 不写的话默认是 master 分支
7.2 Конфигурация клиента центра конфигурации
Использовать элемент заказа в качестве клиента
- в порядке серверного модуля
pom.xml
добавить в файлconfig-client
полагаться
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-client</artifactId>
</dependency>
-
будет
application.yml
переименовать вbootstrap.yml
-
настроить
bootstrap.yml
spring: application: name: order cloud: config: discovery: enabled: true service-id: config #配置中心server的应用名 profile: dev eureka: client: service-url: defaultZone: http://localhost:8761/eureka/
После завершения настройки запустите проект, и он сможет нормально работать.
Уведомление:
- Не забудьте переименовать файл конфигурации
bootstrap.yml
- Настройте URL-адрес службы eureka в локальном файле конфигурации вместо того, чтобы читать его из config, потому что, если номер порта eureka не является значением по умолчанию 8761, он не будет найден.
- Если есть git
order.yml
,order-dev.yml
, сконфигурированный сorder-dev.yml
, он также будет загружаться по умолчанию при загрузкеorder.yml
и объедините два файла. Используя эту функцию, можноorder.yml
Запишите публичную конфигурацию в .
7.3 Конфигурация автоматического обновления Spring Cloud Bus
7.3.1 Добавить зависимость Spring Cloud Bus в проект конфигурации
Добавить зависимость от Spring Cloud BUS в проекте конфигурации
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
Запустите проект и просмотрите его в консоли RabbitMQ: есть соединение, указывающее на то, что конфигурация прошла успешно.
7.3.2 Добавление зависимости Spring Cloud Bus в проект заказа
Добавьте зависимости к серверному модулю порядка, как указано выше.
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
Запускаем и смотрим RabbitMQ, там два подключения
7.3.3 Настройка автоматического обновления
Конфигурация Конфигурация элементовapplication.yml
файл, будетbus-refresh
открытый интерфейс
management:
endpoints:
web:
exposure:
include: "*"
Создайте новый контроллер, чтобы прочитать поле env в удаленной конфигурации.
Метод value принимает конфигурацию
@RestController
@RequestMapping("/env")
@RefreshScope
public class EnvController {
@Value("${env}")
private String env;
@GetMapping("/print")
public String print(){
return env;
}
}
Обязательно добавьте
@RefreshScope
Обратите внимание, в противном случае конфигурация не будет обновляться автоматически.
Запустите оба проекта снова, посетитеhttp://localhost:8899/env/print
Результатом является значение ENV, настроенное на git.
Измените значение env на git, отправьте запрос на публикациюhttp://127.0.0.1:8081/actuator/bus-refresh
Очистить очередь сообщений, затем очиститьhttp://localhost:8899/env/print
Вы увидите, что проект не перезапущен, но значение env изменилось.
Конфигурация префикса
git конфигурация
env: dev5
girl:
name: lili
age: 18
Новый классGirlConfig
@Data
@Component
@ConfigurationProperties("girl")
@RefreshScope
public class GirlConfig {
private String name;
private Integer age;
}
новыйGirlController
@RestController
public class GirlController {
@Autowired
GirlConfig girlConfig;
@GetMapping("girl/print")
public String print(){
return "name= " + girlConfig.getName() + ", age= " + girlConfig.getAge();
}
}
ввод в браузереhttp://localhost:8899/girl/print
, получил ответname= lili, age= 18
.
Измените конфигурацию git, как указано выше, и отправьте почтовый запрос.http://127.0.0.1:8081/actuator/bus-refresh
Обновите очередь сообщений, и вы увидите, что результат также изменился.
Если требуетсяhttp://127.0.0.1:8081/actuator/bus-refresh
Возвращаемое значение равно 500, то есть шина хорошо поработала. Последняя возможная причина заключается в том, что версия,SpringBoot
Изменить версию2.0.0.BUILD-SNAPSHOT
,SpringCloud
версия изменена наFinchley.BUILD-SNAPSHOT
Все должно быть в порядке.
Восемь, основное использование RabbitMQ
Демонстрация заказа проекта
Сначала настройте в файле конфигурацииrabbitmq
Информация. Эти конфигурации могут быть размещены на удаленном git
spring:
rabbitmq:
host: localhost
port: 5672
username: guest
password: guest
8.1 Основное использование
Существует три основных способа получения сообщений.
Способ 1: очередь должна быть объявлена заранее
- Сначала создайте очередь в консоли RabbitMQ.
myQueue
- Снова создайте приемник сообщений и распечатайте его на консоли после получения сообщения.
/**
* RabbitMQ 消息接收者
*/
@Slf4j
@Component
public class MqReceiver {
@RabbitListener(queues = "myQueue")
public void process(String msg){
log.info("reveicer: " + msg);
}
}
-
Создайте отправителя сообщения, напишите метод в тестовом классе для простоты
/** * RabbitMQ 消息发送方 */ @Component public class RabbitMQTest extends OrderApplicationTests { @Autowired AmqpTemplate amqpTemplate; @Test public void test1(){ amqpTemplate.convertAndSend("myQueue", "now " + new Date()); } }
Запуск теста, консоль успешно распечатает принятое сообщение.
Способ 2: автоматическое создание очереди
Во-первых, очередь, созданная первым методомmyQueue
Удалить, отправитель остается без изменений, изменить получателя
@RabbitListener(queuesToDeclare = @Queue("myQueue"))
public void process(String msg){
log.info("reveicer: " + msg);
}
использоватьqueuesToDeclare
Очередь создается автоматически.
Способ 3: автоматически создать очередь и привязать очередь и обмен
Сначала первая очередьmyQueue
Удалить, отправитель остается без изменений, изменить получателя
@RabbitListener(bindings = @QueueBinding(
value = @Queue("myQueue"),
exchange = @Exchange("myExchange")
))
public void process(String msg){
log.info("reveicer: " + msg);
}
8.2 Группировка сообщений
Предположим, что служба заказов состоит из двух групп: цифровых поставщиков и поставщиков фруктов. После размещения заказа компьютерный заказ будет отправлен цифровому поставщику, а заказ фруктов будет отправлен поставщику фруктов. Каждый из двух провайдеров получает свое собственное сообщение.
получатель
/**
* 数码供应商接收消息
* @param msg
*/
@RabbitListener(bindings = @QueueBinding(
exchange = @Exchange("myOrder"),
key = "computer",
value = @Queue("computerOrder")
))
public void processComputer(String msg){
log.info("computerOrder reveicer: " + msg);
}
/**
* 水果供应商接收消息
* @param msg
*/
@RabbitListener(bindings = @QueueBinding(
exchange = @Exchange("myOrder"),
key = "fruit",
value = @Queue("fruitOrder")
))
public void processFruit(String msg){
log.info("fruitOrder reveicer: " + msg);
}
отправитель сообщения
@Test
public void send(){
amqpTemplate.convertAndSend("myOrder", "computer", "now " + new Date());
}
Присланный сюда заказ - это компьютер,convertAndSend()
Три параметра по очередиexchange
, routingKey
, message
Только после отправки сообщенияcomputerOrder
сообщение доставлено.
Глядя на консоль RabbitMQ, вы можете четко увидеть взаимосвязь между обменом и очередью.
Девять, весенний облачный поток
Spring Cloud Stream is a framework for building highly scalable event-driven microservices connected with shared messaging systems.
Промежуточное программное обеспечение сообщений, которое в настоящее время поддерживается Spring Cloud Stream, толькоRabbitMQ
иKafka
9.1 Процедуры
Объединить нижеRabbitMQ
Продемонстрируйте использование Spring Cloud Stream
-
импортировать зависимости
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-stream-rabbit</artifactId> </dependency>
-
Настройте RabbitMQ, как в предыдущем разделе.
spring: rabbitmq: host: localhost port: 5672 username: guest password: guest
-
Создать интерфейс StreamClient
import org.springframework.cloud.stream.annotation.Input; import org.springframework.cloud.stream.annotation.Output; import org.springframework.messaging.MessageChannel; import org.springframework.messaging.SubscribableChannel; public interface StreamClient { String INPUT = "messageInput"; String OUTPUT = "messageOut"; @Input(INPUT) SubscribableChannel input(); @Output(OUTPUT) MessageChannel output(); }
-
Создайте получателя сообщения, где получена первая строка
@Component @EnableBinding(StreamClient.class) @Slf4j public class StreamReceiver { @StreamListener(StreamClient.OUTPUT) public void process(String obj){ log.info("StreamReceiver: " + obj); } }
-
Создать отправителя сообщения
import com.solo.order.message.StreamClient; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.messaging.support.MessageBuilder; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import java.util.Date; @RestController public class SendMessageController { @Autowired private StreamClient streamClient; @GetMapping("/sendMessage") public void send() { String message = "now: " + new Date(); streamClient.output().send(MessageBuilder.withPayload(message).build()); } }
Обратите внимание, что MessageBuilder не указывает неправильный пакет
9.2 Группировка сообщений
Если одновременно открыто несколько экземпляров, возможно, что несколько экземпляров получат сообщения.Чтобы избежать этой проблемы, вы можете использовать группировку сообщений.
добавить в конфигурационный файл
spring:
cloud:
#消息分组
stream:
bindings:
messageInput: #自己定义的队列名
group: order # group 名可以随意起
9.3 Отправка и получение объектов
Дооснащение приемника сообщений
/**
* 接收对象
* @param dto
*/
@StreamListener(StreamClient.OUTPUT)
public void process(OrderDTO dto){
log.info("StreamReceiver: " + dto);
}
Модифицированный отправитель сообщений
/**
* 发送对象
*/
@GetMapping("/sendMessage")
public void send() {
OrderDTO dto = new OrderDTO();
dto.setOrderId("12345678");
streamClient.output().send(MessageBuilder.withPayload(dto).build());
}
Если вы хотите видеть сериализованную строку json вместо имени объекта в консоли MQ, измените конфигурацию следующим образом.
spring:
cloud:
#消息分组
stream:
bindings:
messageInput: #自己定义的队列名
group: order # group 名可以随意起
content-type: application/json #让mq里显示json字符串而不是对象
Добавить кcontent-type: application/json
9.4 Ответ на сообщение
Добавьте два интерфейса в StreamClient
public interface StreamClient {
String INPUT = "messageInput";
String OUTPUT = "messageOut";
String INPUT2 = "messageInput2";
String OUTPUT2 = "messageOut2";
@Input(INPUT)
SubscribableChannel input();
@Output(OUTPUT)
MessageChannel output();
@Input(INPUT2)
SubscribableChannel input2();
@Output(OUTPUT2)
MessageChannel output2();
}
Получатель сообщения вносит следующие изменения
@StreamListener(StreamClient.OUTPUT)
@SendTo(StreamClient.OUTPUT2)
public String process(OrderDTO dto){
log.info("StreamReceiver: " + dto);
return "Received...";
}
@StreamListener(StreamClient.OUTPUT2)
public void process2(String msg){
log.info("StreamReceiver2: " + msg);
}
Главное — добавить@SendTo(StreamClient.OUTPUT2)
Аннотируйте, а затем верните желаемое значение. определить другой приемStreamClient.OUTPUT2
получатель .
10. Установка Redis и простое использование
10.1 Установка
Установить и запустить через Docker
docker run -d -p 6379:6379 redis:4.0.8
Инструмент визуализации Redis под Mac:Redis Desktop Manager
, Относится к РДМ
10.2 Использование
Сначала добавьте зависимости
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
Затем настройте адрес и номер порта redis
spring:
redis:
host: localhost
port: 6379
11. Сервисный шлюз Zuul
11.1 Введение
Элементы сервисного шлюза
- Стабильность и высокая доступность
- производительность, параллелизм
- безопасность
- Расширяемость
Общие шлюзовые решения
- Nginx + Lua
- Kong (на основе Nginx + Lua)
- Tyk
- Spring Cloud Zuul
Особенности Зуула
- маршрут + фильтр
- Ядро представляет собой серию фильтров
Четыре API фильтров Zuul
- Фронт (предварительно)
- Маршрут
- Пост (Пост)
- Ошибка
11.2 Реализация простой маршрутизации и переадресации с помощью Zuul
Создайте новый API-шлюз проекта, отметьте три параметра Cloud Config -> Config Client, CloudDiscovery -> Eureka Discovery, Cloud Routing -> Zuul, нажмите «Далее», чтобы завершить создание.
Исправлятьapplication.properties
файлbootstrap.yml
И выполните следующую настройку
spring:
application:
name: api-gateway
cloud:
config:
discovery:
enabled: true
service-id: config
profile: dev
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
Добавить начальный класс@EnableZuulProxy
аннотация
@SpringBootApplication
@EnableZuulProxy
public class ApiGatewayApplication {
public static void main(String[] args) {
SpringApplication.run(ApiGatewayApplication.class, args);
}
}
Запустите проект на порту 9000, вы можете получить доступ к API других проектов через шлюз
Чтобы получить доступ к проекту продуктаproduct/list
интерфейс, ввод прямо в браузереhttp://localhost:9000/product/product/list
Вот и все.
Формат доступаhttp://localhost:9000/应用id/api地址
11.3 Пользовательская маршрутизация
bootstrap.yml
Добавить к
zuul:
routes:
myProduct: #自己定义的名字
path: /myProduct/**
serviceId: product
может пройтиhttp://localhost:9000/myProduct/product/list
получить доступ к вышеуказанному интерфейсу
Лаконичное письмо
zuul:
routes:
product: /myProduct/**
11.4 Исключение некоторых маршрутов
исключать/product/list
, делая его недоступным
zuul:
routes:
# 简介写法
product: /myProduct/**
# 排除某些路由
ignored-patterns:
- /**/product/list
11.5 Файлы cookie и динамическая маршрутизация
читать куки
По умолчанию файлы cookie будут отфильтрованы. Если вы хотите получить файлы cookie, установитьsensitiveHeaders:
может быть пустым
zuul:
routes:
myProduct:
path: /myProduct/**
serviceId: product
sensitiveHeaders:
Установить конфиденциальные заголовки глобально
zuul:
# 全局设置敏感头
sensitive-headers:
Динамическая настройка маршрутизации
Новое в Gitapi-gateway-dev.yml
Переместите конфигурацию zuul в git
Создайте новый класс конфигурации или напрямую напишите префикс в классе входа, чтобы получить конфигурацию.
@SpringBootApplication
@EnableZuulProxy
public class ApiGatewayApplication {
public static void main(String[] args) {
SpringApplication.run(ApiGatewayApplication.class, args);
}
@ConfigurationProperties("zuul")
@RefreshScope
public ZuulProperties ZuulProperties(){
return new ZuulProperties();
}
}
11.6 Предварительные и постфильтры
Проверка токена с предварительным фильтром
Далее используется предварительный фильтр Zuul для реализации запрошенной проверки токена.
новыйTokenFilter
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import javax.servlet.http.HttpServletRequest;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_DECORATION_FILTER_ORDER;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE;
@Component
public class TokenFilter extends ZuulFilter {
@Override
public String filterType() {
return PRE_TYPE;
}
@Override
public int filterOrder() {
return PRE_DECORATION_FILTER_ORDER - 1;
}
@Override
public boolean shouldFilter() {
return true;
}
@Override
public Object run() throws ZuulException {
RequestContext requestContext = RequestContext.getCurrentContext();
HttpServletRequest request = requestContext.getRequest();
//这里从url里获取,也可以从
String token = request.getParameter("token");
if (StringUtils.isEmpty(token)){
requestContext.setSendZuulResponse(false);
requestContext.setResponseStatusCode(HttpStatus.UNAUTHORIZED.value());
}
return null;
}
}
Запросы без токена сообщат об ошибке 401.
Используйте фильтр сообщений, чтобы добавить содержимое в заголовок возврата.
новыйAddResponseFilter
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletResponse;
import java.util.UUID;
@Component
public class AddResponseFilter extends ZuulFilter {
@Override
public String filterType() {
return FilterConstants.POST_TYPE;
}
@Override
public int filterOrder() {
return FilterConstants.SEND_RESPONSE_FILTER_ORDER - 1;
}
@Override
public boolean shouldFilter() {
return true;
}
@Override
public Object run() throws ZuulException {
RequestContext requestContext = RequestContext.getCurrentContext();
HttpServletResponse response = requestContext.getResponse();
response.addHeader("X-Foo", UUID.randomUUID().toString());
return null;
}
}
добавлено в заголовок возвратаX-Foo
, интерфейс запроса перезапуска проекта обнаружил, что значение было успешно добавлено
11.7 Ограничение тока Зуула
import com.google.common.util.concurrent.RateLimiter;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.exception.ZuulException;
import com.solo.apigateway.exception.RateLimitException;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE;
import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.SERVLET_DETECTION_FILTER_ORDER;
/**
* 限流拦截器. 令牌桶, 用 google 的 guava 实现
*/
public class RateLimitFilter extends ZuulFilter {
public static final RateLimiter RATE_LIMITER = RateLimiter.create(100);
@Override
public String filterType() {
return PRE_TYPE;
}
@Override
public int filterOrder() {
return SERVLET_DETECTION_FILTER_ORDER - 1;
}
@Override
public boolean shouldFilter() {
return true;
}
@Override
public Object run() throws ZuulException {
if (RATE_LIMITER.tryAcquire()){
throw new RateLimitException();
}
return null;
}
}
12. Аутентификация Zuul и добавление пользовательских сервисов
быть улучшенным
Тринадцать, междоменный Зуул
Существует множество решений междоменных проблем, которые можно аннотировать на одном интерфейсе или единообразно обрабатывать на шлюзе Zuul.
13.1 Добавьте аннотации к интерфейсам для достижения междоменного взаимодействия
добавить в интерфейс@CrossOrigin
Аннотация может сделать этот интерфейс междоменным
13.2 Zuul решает междоменную проблему
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
import java.util.Arrays;
/**
* 跨域配置
*/
@Configuration
public class CorsConfig {
@Bean
public CorsFilter corsFilter() {
final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
final CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true); //是否支持 cookie 跨域
config.setAllowedHeaders(Arrays.asList("*"));
config.setAllowedOrigins(Arrays.asList("*"));
config.setAllowedMethods(Arrays.asList("*"));
config.setMaxAge(300l); //缓存时间。在这个时间段内,相同的跨域请求将不再检查
source.registerCorsConfiguration("/**", config);
return new CorsFilter(source);
}
}
По мере развития проекта с открытым исходным кодом на более позднем этапе будет написан ряд статей, чтобы подробно представить эти технологии в сочетании с реальным боем проекта.Добро пожаловать, чтобы обратить внимание~
адрес проекта:GitHub.com/cache Cats/ из…