单机模式下nacos的安装与使用

一、nacos 的安装(安装包方式)

① 下载安装包 https://nacos.io/download/nacos-server/ 并进行解压缩

unzip nacos-server-$version.zip
# 或者 tar -xvf nacos-server-$version.tar.gz
cd nacos/bin

② 修改配置文件 application.properties ,有 3 个与 客户端访问鉴权 相关的必填项,如果没有填写的话,启动服务时会被要求在控制台输入

### The default token (Base64 String):
nacos.core.auth.plugin.nacos.token.secret.key=

### Since 1.4.1, worked when nacos.core.auth.enabled=true and nacos.core.auth.enable.userAgentAuthWhite=false.
### The two properties is the white list for auth and used by identity the request from other server.
nacos.core.auth.server.identity.key=
nacos.core.auth.server.identity.value=

(可选)默认情况下,如果不做额外配置,Nacos 会使用嵌入式的 Derby 数据库(无需单独安装),适用于测试或轻量级部署场景,如果想将数据持久化至 mysql,需要修改配置文件

nacos 所需的数据脚本在 conf 目录下,最好提前跑一下,不确定 nacos 能否自动建表

#*************** 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?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=Asia/Shanghai
# db.user.0=nacos
# db.password.0=nacos

### Connection pool configuration: hikariCP
db.pool.config.connectionTimeout=30000
db.pool.config.validationTimeout=10000
db.pool.config.maximumPoolSize=20
db.pool.config.minimumIdle=2

### the maximum retry times for push
nacos.config.push.maxRetryTime=50

④ 启动服务 sh startup.sh -m standalone(Linux) 或者 startup.cmd -m standalone(Windows)

⑤ 进入 ${nacos.home}/logs/ 目录下, 使用 tail -f start.out 查看日志,如果看到如下日志,说明服务启动成功

Nacos started successfully in stand alone mode. use embedded storage

⑥ nacos 控制台页面为 http://{ip}:{port}/{context}/index.html ,例如

http://192.168.89.1:8849/nacos/index.html

初始管理员用户和密码都为 nacos

二、nacos 的安装(docker方式)

docker run --name nacos-standalone-derby \
    -e MODE=standalone \
    -e NACOS_AUTH_TOKEN=${your_nacos_auth_secret_token} \
    -e NACOS_AUTH_IDENTITY_KEY=${your_nacos_server_identity_key} \
    -e NACOS_AUTH_IDENTITY_VALUE=${your_nacos_server_identity_value} \
    -p 8080:8080 \
    -p 8848:8848 \
    -p 9848:9848 \
    -d nacos/nacos-server:latest

通过 docker logs -f $container_id 命令,查看 Nacos 服务启动日志,如果看到如下日志,说明服务启动成功

Nacos started successfully in xxxx mode. use xxxx storage

关于暴露出来的这 3 个端口,参考 https://nacos.io/blog/faq/nacos-user-question-history15151/

三、nacos 的使用

在 maven 项目中引入 nacos discovery 依赖

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

在 application.yaml 中配置 nacos 地址

server:
  port: 8081
spring:
  application:
    name: order-service
  cloud:
    nacos:
      server-addr: 192.168.19.130:8848

在项目主类上添加 @EnableDiscoveryClient 注解

@SpringBootApplication
@EnableDiscoveryClient
public class NacosProviderApplication {
    // ... 其他代码 ...
}

最后,启动项目即可完成自动注册,在 nacos 控制台中可以看到对应的服务

四、发现并调用服务

使用 Spring Cloud 提供的 DiscoveryClient 类获取服务提供者,并通过 RestTemplate 自行进行服务调用,代码如下

RestTemplate 是 Spring 内置的框架,包名 package org.springframework.web.client

/**
 * 购物车 服务实现类
 */
@Service
@RequiredArgsConstructor
public class CartServiceImpl extends ServiceImpl<CartMapper, Cart> implements ICartService {

    private final RestTemplate restTemplate;

    private final DiscoveryClient discoveryClient;
    
    // 查询购物车中的商品信息
    private void queryProductInfos(List<CartVO> carts) {
        // 想查询详情的商品id
        Set<Long> itemIds = ...;
        // 获取商品服务列表
        List<ServiceInstance> instances = discoveryClient.getInstances("product-service");
        if(CollUtil.isEmpty(instances)) {
            return;
        }
        // 随机选择一个商品服务的实例
        ServiceInstance instance = instances.get(RandomUtil.randomInt(instances.size()));
        
        // 调用商品服务
        ResponseEntity<List<ItemDTO>> response = restTemplate.exchange(
                instance.getUri() + "/items?ids={ids}",   // http://192.168.89.1:8081/items?ids=1,2,3
                HttpMethod.GET,
                null,
                new ParameterizedTypeReference<List<ItemDTO>>() { },
                Map.of("ids", CollUtil.join(itemIds,","))
        );
        if(!response.getStatusCode().is2xxSuccessful()) {
            // 查询失败,直接结束
            return;
        }
        List<ItemDTO> items = response.getBody();
        
        // ...后续逻辑
    }
}

也可以在 RestTemplate 上添加 @LoadBalanced(Spring Cloud 提供的标记注解),这样 RestTemplate 就会支持负载均衡功能,可以直接使用服务名进行 HTTP 请求的发送

原理是注册了一个 RestTemplate 的拦截器 LoadBalancerInterceptor,该拦截器会使用 LoadBalancerClient(Spring Cloud 提供) 接口的实现类 BlockingLoadBalancerClient(默认)或者 RibbonLoadBalancerClient 完成负载均衡

补充,在新的版本(Spring Cloud 版本 2020.0.x 及以后)中官方推荐使用 Spring Cloud LoadBalancer 实现负载均衡方案

五、使用 OpenFeign 实现服务调用

在服务调用方的工程中引入依赖

<!--openFeign-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!--负载均衡器,也可以不添加这个依赖-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>

在启动类上添加注解 EnableFeignClients,开启 OpenFeign 功能

@EnableFeignClients
// @EnableFeignClients(basePackages = "com.mall.api.client", defaultConfiguration = DefaultFeignConfig.class) // 可以指定feign的扫描包和全局配置类
@SpringBootApplication
public class CartApplication {
    public static void main(String[] args) {
        SpringApplication.run(CartApplication.class, args);
    }
}

在服务调用方编写 OpenFeign 客户端

@FeignClient("provider-service") // 声明服务提供方
// @FeignClient(value = "provider-service", configuration = DefaultFeignConfig.class) // 可以在某个FeignClient中指定配置类,只对当前FeignClient生效
public interface ProviderClient {

    @GetMapping("/items")
    List<ItemDTO> queryProductByIds(@RequestParam("ids") Collection<Long> ids);
}

有了上述信息,OpenFeign 就可以利用动态代理帮我们实现这个方法,当我们调用该方法时,OpenFeign 就会向 http://provider-service/items 发送一个 GET 请求

/**
 * 购物车
 */
@Service
@RequiredArgsConstructor
public class CartServiceImpl extends ServiceImpl<CartMapper, Cart> implements ICartService {

    private final ProviderClient providerClient;
    
    // 查询购物车中的商品信息
    private void queryCartItems(List<CartVO> vos) {
        // 获取商品id
        Set<Long> itemIds = ...;

        // 使用 OpenFeign 接口查询商品服务
        List<ItemDTO> items = providerClient.queryItemByIds(itemIds);

        // 后续逻辑...
    }
}
posted @ 2025-11-03 12:26  鹿鹿脖子长  阅读(38)  评论(0)    收藏  举报