第一代SpringCloud即SpringCloud Netflix很多组件已经停止更新和维护了,迫使我们必须要找到一个可以代替Netflix的第二代产品,这时SpringCloud Alibaba出现了。Nacos是SpringCloud Alibaba的核心组件,它充当了配置中心 + 注册中心的角色。
下载与启动
下载解压后,conf文件夹下的nacos-mysql.sql到数据库执行一下(我用的是Mysql8,数据库先建好);表创建好后,编辑下conf文件夹下的application.properties:
修改好后,打开cmd窗口,切换到解压目录下的bin文件夹下,运行:
startup.cmd -m standalone
浏览器访问这个地址:
然后输入默认的用户名、密码:nacos、nacos,看到下面这个页面,说明启动成功:
配置中心
项目中的一些配置项,直接就放到nacos中了。需要在浏览器打开的nacos管理页面上,手动创建:
之后我们在idea中创建SpringCloud项目,创建bootstrap.yml:
spring.cloud.nacos.config.server-addr指定nacos的地址,这个模块和nacos中创建的配置文件如何对应呢?在于截图中的三个配置:spring.application.name + “-” + spring.profiles.active + “.” + spring.cloud.nacos.config.file-extension,对于如上的配置,就是nacos_config-dev.yml。项目启动后,会去nacos的配置列表里查找,查找Data Id为nacos_config-dev.yml的配置。
上面说的查找方式不太完整,完整的是按照命名空间 - group - Data Id查找。命名空间、group由bootstrap.yml中spring.cloud.nacos.config.namespace、spring.cloud.nacos.config.group来指定,默认值是public、DEFAULT_GROUP。我们刚才创建的配置,是在public命名空间下、DEFAULT_GROUP group下的,所以没有配置用默认值刚好能对应上。读者也可以在nacos中再创建个命名空间、或者换个group来试下。
代码层面,首先引入依赖:
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
<version>2.2.0.RELEASE</version>
</dependency>
然后取值,建一个控制器:
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping("/user")
@RefreshScope
public class UserController {
@Value("${person.name}")
private String name;
@Value("${person.age}")
private Integer age;
@GetMapping("/sayHello")
public void sayHello() {
System.out.println("name:" + name + "," + "age:" + age);
}
}
类上的@RefreshScope用来自动刷新。如果nacos上的配置修改了,代码中获取的值也能同步更新,不用重启服务。
注册中心
在bootstrap.yml中配置:
核心的就是spring.application.name(指定服务名称)和spring.cloud.nacos.discovery.server-addr这2个注解。当然和配置中心一样,也有命名空间和group,由spring.cloud.nacos.discovery.namespace和spring.cloud.nacos.discovery.group指定,默认值为public和DEFAULT_GROUP。
引入依赖:
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
<version>2.2.0.RELEASE</version>
</dependency>
然后直接运行启动类,启动项目即可。之前较低版本,启动类上还要添加@EnableDiscoveryClient注解,现在高版本不需要了。启动后,我们就能够在nacos管理页面看到:
和配置中心类似,某一服务想要调用另一服务的接口,也是命名空间 - group - 服务名称查找。也就是,两个服务在同一命名空间、group相同的情况下,能够互相通信了。
服务提供方(nacos-provider服务对应的模块)提供方法:
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
@RequestMapping("/provide")
public class ProviderController {
@RequestMapping("/distribute")
@ResponseBody
public String distribute() {
return "发鸡胸肉";
}
}
服务调用方(另一模块,pom.xml引入同样的依赖:spring-cloud-starter-alibaba-nacos-discovery),启动类添加:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
@SpringBootApplication
public class NacosConfigApplication {
public static void main(String[] args) {
SpringApplication.run(NacosConfigApplication.class, args);
}
@LoadBalanced
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
调用提供方方法:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.client.RestTemplate;
@Controller
@RequestMapping("/user")
public class UserController {
@Autowired
private RestTemplate restTemplate;
@GetMapping("/invoke")
public void invoke() {
String str = restTemplate.getForObject("http://nacos-provider/" +
"nacosProvider/provide/distribute", String.class);
System.out.println(str);
}
}