Я новичок в Spring, и мой вопрос довольно простой, но я думаю, что не могу найти ни одного хорошего ресурса. Я просмотрел примеры для начинающих (например, это, это и некоторые другие) и искал ответы в StackOverflow, но я не совсем уверен, что мне нужно искать.
Позвольте мне объяснить сценарий. Скажем, у меня есть центральный узел (C) и несколько внутренних узлов (I_1, ..., I_n), и этот случай:
I_1
.
. ------------------> C
.
I_n
На этом очень простом рисунке я пытаюсь проиллюстрировать, что каждый I_i отправляет что-то в C, когда C просит об этом. Вот и все. Теперь я хочу, чтобы у каждого I_i был специальный идентификатор, и они отправляют этот идентификатор в C. Как мне смоделировать это в Spring? На данный момент у меня есть базовая настройка
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
И у меня есть контроллер
@RestController
public class Controller {
@RequestMapping(value = "/i1/{id}", method = RequestMethod.GET)
@ResponseBody
public String i1(
@PathVariable("id") String id) {
return id;
}
}
Так что, если я запустил этот код и скрутил его до http: // локальный: порт / i1 / 560, он вернет 560. Я, конечно, могу создать несколько узлов этого кода, например, создав файл jar и запустив его на разных портах. Проблема в том, что я не могу дать им уникальные идентификаторы. Я имею в виду, что все они являются экземпляром приложения. Я бы хотел, чтобы они относились к классу узлов ниже (или что-то подобное):
class node{
private int id;
public node(int id){
this.id = id;
}
}
Так что у меня будет n внутренних узлов. А затем я могу открыть терминал и скрутить каждого из них, чтобы получить их идентификатор. Надеюсь, я достаточно хорошо объяснил. Вкратце: моя цель - иметь n экземпляров класса узла с уникальным идентификатором. И я хочу скрутить их по отдельности и получить их идентификаторы, например «curl http: // локальный: 8081 / i1» вернет идентификатор i1, а «curl http: // локальный: 8082 / i2» вернет идентификатор i2 и так далее. Я даже не уверен, какие ключевые слова использовать при поиске. Я пробовал «создать несколько клиентов / хостов / приложений», но на самом деле не нашел нужного, поэтому я даже был бы признателен за ответ, который содержит только это.
Бобы
Я прочитал этот пример, который на самом деле не использует контроллер, но использует beans. Я пробовал этот подход, и это похоже на то, что я хочу сделать, он может создавать несколько узловых объектов, все с уникальным идентификатором. Однако я не уверен, смогу ли я подключить каждый из них к разным узлам и портам.
@jAC Да, наверное. Чтобы уточнить, прямо сейчас у меня есть части приложения и контроллера. Я создаю JAR-файл с этим кодом. Затем я запускаю его несколько раз с разными портами, используя java -Dserver.port = <port> -jar <file>. И я хочу, чтобы это было так, если возможно. Таким образом я получаю несколько узлов на разных портах.
Хорошо, и каждый узел должен прослушивать отдельный порт или все это должно работать в одном экземпляре?
@jAC каждый узел должен прослушивать отдельные порты. Если я запустил файл jar четыре раза, как я писал выше, на портах 8080, ..., 8083, я создам 4 узла. Я хочу, чтобы это были I_1, ..., I_4. Поэтому, когда я скручиваю http: // (...) / I1, I1 ответит своим идентификатором и так далее. Так что я могу собрать все их идентификаторы, скручивая их.
Какие-либо ограничения на идентификатор узла?
@ Ян Ларсен, не совсем. ID был просто примером. Это может быть что угодно, возможно, даже что угодно из таблицы ASCII. Он должен быть отправлен из I_i в C, но я могу просто преобразовать его в какой-то формат, который легко отправить.




Ваша установка с одним узлом и одним контроллером в одном приложении с одним портом проста, но, вероятно, вызовет проблемы с памятью на этом пути. Вы, вероятно, захотите одно приложение, которое запускает потоки узлов, каждый из которых принимает порт.
Принимая ваш вопрос за чистую монету, проще всего было бы создать компоненты узлов, используя «прототип» @Scope (чтобы они не были одиночными, если вы добавите еще один позже), затем один @Autowire на ваш контроллер, затем используйте UUID для идентификатора, чтобы он всегда был уникальным и просто установите его при создании узла:
private UUID id = UUID.randomUUID();
с геттером. Затем контроллер может получить идентификатор от своего собственного узла.
Вы имеете в виду что-то вроде это? Как мне убедиться, что они работают на разных портах?
Итак, я думаю, что ваше основное требование довольно легко выполнить.
Но все же есть вопросы по индексу ваших узлов I_x. Почему они вообще имеют значение?
Если у вас есть порт и идентификатор вашего узла, этого достаточно для идентификации узла. Итак, я создал ответ со следующими двумя свойствами:
Следуя указанным выше ограничениям, вы не можете создать Controller, который прослушивает определенное отображение I_x. Но, как я понимаю, в этом нет особой необходимости.
Создайте класс NodeInformation, содержащий значения:
@Getter
@Setter
public class NodeInformation {
private int port;
private int id;
public NodeInformation(int port, int id) {
this.port = port;
this.id = id;
}
}
@Getter и @Setter - это аннотации org.projectlombok, которые автоматически создают сеттер и получатель.
Затем введите необходимую информацию, проанализировав вашу конфигурацию. Эта конфигурация может быть установлена:
-Dnode.port=xy-Dnode.id=myid)ВНИМАНИЕ: В качестве альтернативы вы можете использовать свойство пружины server.port, которое автоматически устанавливает порт.
Итак, заполнив информацию в вашем NodeInformation, вы должны использовать @ConfigurationNodeInformationConfiguration, который собирает и возвращает ваш Bean:
@Configuration
public class NodeInformationConfiguration {
private final int port;
private final int id;
public NodeInformationConfiguration(@Value("${node.port}") int port, @Value("${node.id}") int id) {
this.port = port;
this.id = id;
}
@Bean
public NodeInformation getNodeInfo() {
return new NodeInformation(port, id);
}
}
Итак, в конце вы должны установить свой порт и создать контроллер, который возвращает ваш идентификатор.
Настройка порта
Вы можете настроить свой порт с помощью EmbeddedServletContainerCustomizer. Используйте NodeInformation, который мы ранее создали, автоматически подключив его к вашему классу PortSetter.
@Component
public class PortSetter {
private final int port;
@Autowired
public PortConfiguration(NodeInformation nodeInformation) {
this.port = nodeInformation.getPort();
}
@Bean
public EmbeddedServletContainerCustomizer containerCustomizer() {
return (container -> {
container.setPort(port);
});
}
}
И, наконец, создайте простой RestController, который возвращает идентификатор вашего набора, прослушивая /id:
@RestController
public class NodeController {
private final NodeInformation nodeInformation;
@Autowired
public NodeController(NodeInformation nodeInformation) {
this.nodeInformation = nodeInformation;
}
@RequestMapping("/id")
public int getNodeId() {
return this.nodeInformation.getId();
}
}
Итак, вы хотите, чтобы один исполняемый файл работал с разными конфигурациями (портами)?