Облачное решение = DevOps + CI/CD + контейнеризация
dns,VIP (виртуальный IP),address-server
Поддержка http, dns, udp, tls.
можетиспользовать ConfigService и NamingService(Служить Обнаружить) Две основные функцииnacos.core.auth.enabled=true #Включить аутентификацию
nacos.core.auth.server.identity.key=nacosIdKey #Устанавливаем значение ключа
nacos.core.auth.server.identity.value=nacosIdValue #Установить значение
### The default token (Base64 String):
nacos.core.auth.plugin.nacos.token.secret.key=SecretKey012345678901234567890123456789012345678901234567890123456789
Выполнить автономный запуск.cmd -m
Укажите одну машинузапускать,Значение по умолчанию:кластерзапускать<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.0.7</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.cheese</groupId>
<artifactId>springcloudalibaba</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<name>springcloudalibaba</name>
<description>springcloudalibaba</description>
<modules>
<module>01-provider-nacos-8081</module>
<module>02-consumer-nacos-8080</module>
<module>03-provider-config-8081</module>
<module>04-consumer-openfegin-8080</module>
</modules>
<properties>
<java.version>17</java.version>
<spring-cloud.version>2022.0.0</spring-cloud.version>
<spring-cloud-alibaba.version>2022.0.0.0-RC2</spring-cloud-alibaba.version>
</properties>
<!--Управление подпроектамиизspringcloudalibabaВерсия-->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring-cloud-alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
</dependencies>
</project>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<!--обозначение父工程gav-->
<parent>
<groupId>com.cheese</groupId>
<artifactId>springcloudalibaba</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>01-provider-nacos-8081</artifactId>
<packaging>jar</packaging>
<name>01-provider-nacos-8081</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/com.alibaba/druid -->
<!--外部полагатьсянуждатьсяобозначениеversion-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.23</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
</dependencies>
</project>
server:
port: 8081
spring:
#микросервисыимя application:
name: depart-provider
spring:
jpa:
generate-ddl: true #При указании запуска контейнера Spring таблица создателя по умолчанию имеет значение дляfalse
show-sql: true #sql Независимо от того, отображается ли в консоли операторы sql, значение по умолчанию — дляfasle.
hibernate:
ddl-auto: none #Установить, чтобы таблица не обновлялась при применении Перезапуска
-- auto-generated definition
create schema alibaba2024 collate utf8mb4_0900_ai_ci;
use alibaba2024;
-- auto-generated definition
create table depart_entity
(
id int not null
primary key,
name varchar(255) null
);
@Data
@Entity
@JsonIgnoreProperties({"hibernateLazyInitializer","handler","fieldHandler"})
/**
* Объект запроса JPA, отложенная загрузка по умолчанию, игнорировать отложенную загрузку
*/
public class DepartEntity {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)//самовозрастающийID public Integer id;
public String name;
}
@RequestMapping("/provider/depart")
@RestController
public class DepartController {
@Autowired
private DepartService departService;
/**
* Как правило, в производственной среде середина будет иметь одно и то же имя интерфейса, и для их различения используется метод запроса CRUD.
* @param depart
* @return
*/
//Новый
@PostMapping("/save")
public Boolean addDepart(@RequestBody DepartEntity depart) {
return departService.addDepart(depart);
}
//удалить
@DeleteMapping("/del/{id}")
public Boolean deleteDepart(@PathVariable("id") Integer id) {
return departService.deleteDepartById(id);
}
//Исправлять
@PutMapping("/update")
public Boolean updateDepart(@RequestBody DepartEntity depart) {
return departService.updateDepart(depart);
}
//Получать
@GetMapping("/get/{id}")
public DepartEntity getDepart(@PathVariable("id") Integer id) {
return departService.getDepartById(id);
}
//список
@GetMapping("/list")
public List<DepartEntity> getDepartList() {
return departService.getAllDepart();
}
}
public interface DepartService {
//insert
boolean addDepart(DepartEntity depart);
//update
boolean updateDepart(DepartEntity depart);
//delete
boolean deleteDepartById(Integer id);
//get
DepartEntity getDepartById(Integer id);
//Query
List<DepartEntity> getAllDepart();
}
@Service
public class DepartServiceImpl implements DepartService {
@Resource
private DepartRepository departRepository;
@Override
public boolean addDepart(DepartEntity depart) {
return departRepository.save(depart) != null;
}
@Override
public boolean updateDepart(DepartEntity depart) {
return addDepart(depart);//JPA, лежащий в основе метода saveOrUpdate, различает, является ли входящий атрибут идентификатора объекта нулевым
}
@Override
public boolean deleteDepartById(Integer id) {
if (departRepository.existsById(id)) {
departRepository.deleteById(id);
return true;
}
return false;
}
@Override
public DepartEntity getDepartById(Integer id) {
if (departRepository.existsById(id)) {
return departRepository.getReferenceById(id);
}
DepartEntity depart = new DepartEntity();
depart.setName("not exist this depart");
return depart;
}
@Override
public List<DepartEntity> getAllDepart() {
return departRepository.findAll();
}
}
public interface DepartRepository extends JpaRepository<DepartEntity, Integer> {
}
# номер порта
server:
port: 8080
spring:
#микросервисыимя application:
name: depart-consumer
@Configuration
public class DepartConfig {
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
@RestController
@RequestMapping("/consumer/depart")
public class DeportController {
@Resource
private RestTemplate restTemplate;
//Режим прямого подключения
public static final String SERVICE_PROVIDER = "http://localhost:8081/provider/depart";
//Новый
@PostMapping("/")
public Boolean addDepart(@RequestBody DepartEntity depart) {
return restTemplate.postForObject(SERVICE_PROVIDER + "/save", depart, Boolean.class);
}
//Исправлять
@PutMapping("/")
public void modifyDepart(@RequestBody DepartEntity depart) {
restTemplate.put(SERVICE_PROVIDER + "/update", depart);
}
//удалить
@DeleteMapping("/{id}")
public void deleteDepart(@PathVariable Integer id) {
restTemplate.delete(SERVICE_PROVIDER + "/del/" + id);
}
//запрос
@GetMapping("/{id}")
public DepartEntity getDepart(@PathVariable Integer id) {
return restTemplate.getForObject(SERVICE_PROVIDER + "/get/" + id, DepartEntity.class);
}
//список
@GetMapping("/list")
public List<DepartEntity> getDepartList() {
return restTemplate.getForObject(SERVICE_PROVIDER + "/list", List.class);
}
}
spring:
cloud:
nacos:
discovery:
server-addr: localhost:8848 #nacosзарегистрироватьсясерединаheart адрес
username: nacos
password: nacos
//Режим прямого подключения
//public static final String SERVICE_PROVIDER = "http://localhost:8081/provider/depart";
//метод вызова микросервиса
public static final String SERVICE_PROVIDER = "http://depart-provider/provider/depart";
Примечание. После версии nacos 2.2.0.1 от балансировщика нагрузки ленточного клиента отказались и использовали балансировщик нагрузки сообщества Springcloud. К потребителю необходимо добавить следующие зависимости.
<!--nacos2.2.0.1позже Версияиз Зависимости балансировки нагрузки клиента-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
@Configuration
public class DepartConfig {
@Bean
//Нагрузка вызывается так же, компонент Netflix серединаиз балансировки нагрузки существующегоnacosсередина больше не используется,
//nacosиспользоватьновыйиз использует Spring-cloud-starter-loadbalancer для реализации балансировки клиентской нагрузки
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
depart-provider
измикросервисы
@RequestMapping("/provider/depart")
@RestController
public class DepartController {
.....
@Autowired
private DiscoveryClient discoveryClient; //Служитьоткрыть клиента
@GetMapping("/discovery")
public List<String> discoveryHandle() {
List<String> services = discoveryClient.getServices();
services.forEach(v1->{
//Получатьмикросервисыимяизвсемикросервисы Пример
discoveryClient.getInstances(v1).forEach(v2->{
HashMap<String, Object> map = new HashMap<>();
map.put("serviceName", v1);
map.put("serviceId", v2.getServiceId());
map.put("serviceHost", v2.getHost());
map.put("servicePort", v2.getPort());
map.put("uri", v2.getUri());
System.out.println("map = " + map);
});
});
return services; //Вернем имена всех активных измикросервисов
}
.......
}
spring:
cloud:
nacos:
discovery:
ephemeral: false #Установить, является ли это временным узлом, по умолчанию установлено дляtrue, для временного узла, false, установлено не для временного узла, то есть постоянный экземпляр,ужезарегистрироватьсяиз Временный экземпляр Нет Исправлятьдляпостоянный экземпляр
curl -d 'serviceName=depart-provider' \
-d 'ip=192.168.1.102' \
-d 'port=8081' \
-d 'ephemeral=false' \
-d 'username=nacos' \
-d 'password=nacos' \
-X DELETE 'http://127.0.0.1:8848/nacos/v2/ns/instance'
По умолчанию согласованность данных кластера Nacos Discovery использует режим AP. Но он также поддерживает режим CP и его необходимо конвертировать. Чтобы преобразовать в CP, вы можете отправить следующий запрос PUT для завершения преобразования из AP в CP.
nacos-server-2.2.1\nacos\conf
по путиcreate database nacos_config
#*************** Config Module Related Configurations ***************#
### If use MySQL as datasource:
### Deprecated configuration property, it is recommended to use `spring.sql.init.platform` replaced.
spring.datasource.platform=mysql
spring.sql.init.platform=mysql
### Count of DB:
db.num=1
### Connect URL of DB:
db.url.0=jdbc:mysql://127.0.0.1:3306/nacos_config?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC
db.user.0=root
db.password.0=abc123
cluster.conf
#номер oНепрерывное предотвращение занятости системных портов
192.168.1.102:8849
192.168.1.102:8851
192.168.1.102:8853
startup.cmd
по умолчаниюкластерзапускатьspring:
cloud:
nacos:
discovery:
#server-addr: localhost:8848 #nacosзарегистрироватьсясерединаheart адрес
#кластерзарегистрироваться
server-addr: localhost:8849,localhost:8851,localhost:8853 #nacosзарегистрироватьсясерединаheart адрес
username: dev
password: dev01
Независимо от способа развертывания, пользователям рекомендуется поместить все сервисные узлы в кластере Nacos под VIP, а затем повесить их под доменное имя.
<http://ip1:port/openAPI>
Если в режиме прямого IP-соединения машина зависает, вам необходимо изменить IP-адрес, прежде чем его можно будет использовать.<http://SLB:port/openAPI>
Режим монтирования SLB (SLB внутренней сети, не может быть открыт для общедоступной сети во избежание угроз безопасности), просто подключайтесь к SLB напрямую, а ниже висит реальный IP-адрес сервера, который не читается.<http://nacos.com:port/openAPI>
доменное имя + Режим SLB (SLB внутренней сети, не может быть доступен в общедоступной сети во избежание угроз безопасности), хорошая читаемость и легкость изменения IP-адреса, рекомендуемый режим
существоватьиспользоватьVIPчас,нужно быть открытымNacosСлужитьизхозяинпорт(по умолчанию8848)а такжеgRPCпорт(по умолчанию9848)、同час如果верноNacosизхозяинпорт Что-нибудь Исправлятьизразговаривать,нужноvipсерединаизпорт映射делать出Конфигурация,специфическийпортиз Справочник по методу сопоставленияОбзор руководства по развертыванию — архитектура развертывания Nacos
Службы в Nacos однозначно идентифицируются тройкой: пространство имен, группа и служба имен служб. Роль пространства имен и группы та же, они используются для разделения различных областей и изоляции сервисов. Разница в том, что область действия пространства имен больше, и одна и та же группа может содержаться в разных пространствах имен. Разные группы могут содержать одну и ту же услугу. Значение по умолчанию для пространства имен — public, а значение по умолчанию для группы — DEFAULT GROUP. . Отношения между ними показаны на официальном рисунке ниже.
Запустите три экземпляра провайдера-nacos-8081, предоставляющие одну и ту же службу, другое пространство имен, группу и порт.
пространство имен | Название группы | номер порта |
---|---|---|
public | DEFAULT_GROUP | 8081 |
public | MY_GROUP | 8082 |
ns_test | MY_GROUP | 8083 |
@Service
public class DepartServiceImpl implements DepartService {
@Resource
private DepartRepository departRepository;
//Получатьномер порта
@Value("${server.port}")
private Integer port;
@Override
public DepartEntity getDepartById(Integer id) {
if (departRepository.existsById(id)) {
return departRepository.getReferenceById(id);
}
DepartEntity depart = new DepartEntity();
depart.setName("not exist this depart port: "+ port);
return depart;
}
}
Файл конфигурации каждого хоста в кластере один и тот же, поэтому обновление и поддержка файла конфигурации становится сложной проблемой. В это время появился центр конфигурации, и файлы конфигурации каждого узла кластера были переданы в центр конфигурации для единого управления. Существует множество сопутствующих продуктов, таких как конфигурация Spring Cloud, Zookeeper, Apollo, Disconf и т. д. Однако Spring Cloud Alibaba официально рекомендует использовать Nacos в качестве центра настройки микросервисов. "
Есть три основные проблемы:
Его клиент Config может автоматически обнаруживать обновления файлов конфигурации. Но есть и два недостатка:
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
bootstrap.yaml
документ,новая версия nacos местный Конфигурациядокумент Ренрандля application.yaml
spring:
#микросервисыимя application:
name: depart-provider
cloud:
nacos:
config:
server-addr: localhost:8848
username: nacos
password: nacos
spring:
cloud:
nacos:
config:
file-extension: yaml #read из Конфигурациятип документа
spring:
# новая версия Новый Конфигурация
config:
import:
- optional:nacos:${spring.application.name}.${spring.cloud.nacos.config.file-extension}
spring:
cloud:
nacos:
config:
#выполнить Общая компоненты, предварительное условие, одно и то же пространство имен, одна и та же группа, разные Служить совместное использование
shared-configs[0]:
data-id: shareconfig.yaml
refresh: true
shared-configs[1]:
data-id: shareconfig2.yaml
refresh: true
#Для достижения расширения Конфигурация можно использовать совместно разные пространства имен и разные группы.
extension-configs[0]:
data-id: extensionconfig.yaml
refresh: true
extension-configs[1]:
data-id: extensionconfig2.yaml
refresh: true
# Порядок загрузки конфигурации: Общая конфигурация=>Расширять Конфигурация=>когда前Конфигурация
# Приоритет конфигурации: после загрузкииз Сначала перезапишу и загрузюиз=> когда前Конфигурация>Расширять Конфигурация>Общая конфигурация
Эти три файла с одинаковым именем также имеют проблемы с порядком загрузки. Их порядок загрузки следующий: локальный файл конфигурации, удаленный файл конфигурации, файл конфигурации моментального снимка. Пока система загружает файл конфигурации, последующие больше не будут загружаться.
@Service
@RefreshScope //Достигаем динамического обновления
public class DepartServiceImpl implements DepartService {
@Resource
private DepartRepository departRepository;
//Получатьномер порта
@Value("${server.port}")
private Integer port;
//Получать部门имяпроходить远程Конфигурациясередина Сердце
@Value("${depart.name}")
private String departName;
@Override
public DepartEntity getDepartById(Integer id) {
if (departRepository.existsById(id)) {
return departRepository.getReferenceById(id);
}
DepartEntity depart = new DepartEntity();
depart.setName("not exist this depart"+departName+" port: "+ port);
return depart;
}
}
существуют При разработке приложений обычно один и тот же набор программ используется в нескольких различных средах, таких как среда разработки, тестирования, производственная среда и т. д. Каждая среда избаза данныхадрес、Служитьустройствономер порт и прочее Конфигурация будет другая. Если в разных средах содержимое бега разное, то такой подход не только очень громоздкий, но и подвержен ошибкам. На данный момент вам необходимо определить разную информацию и выбрать разные конфигурации для разных сред.
depart-provider.yaml
руководить克隆application.yaml
документсередина做ниже Конфигурацияspring:
profiles:
active: dev
# новая версия Новый Конфигурация
config:
import:
- optional:nacos:${spring.application.name}-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
Запустите три экземпляра поставщика-конфигурации-8081, предоставляющие одну и ту же службу, разное пространство имен, группу и порт.
пространство имен | Название группы | номер порта |
---|---|---|
public | DEFAULT_GROUP | 8081 |
public | MY_GROUP | 8082 |
ns_test | MY_GROUP | 8083 |