服务治理的核心由三部分组成:服务提供者、服务消费者、注册中心。在分布式系统架构中,每个微服务在启动时,将自己的信息存储在注册中心,叫做服务注册。服务消费者从注册中心获取服务提供者的网络信息,通过该信息调用服务,叫做服务发现。
服务的提供者&服务的消费者是相对的概念:
本例搭建是伪集群,在一台虚拟机上起3个nacos服务,使用nginx做负载均衡。
下载地址:https://github.com/alibaba/Nacos/releases
tar -xzvf nacos-server-1.1.4.tar.gz
编辑conf/application.properties文件:
#mysql数据库连接信息,需要自己创建数据库,sql脚本在conf/nacos-mysql.sql
server.port=8849 #3个nacos服务端口号分别为8849,8850,8851
spring.datasource.platform=mysql
db.num=1
db.url.0=jdbc:mysql://192.168.1.14:3306/nacos?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true
db.user=root
db.password=123456
将conf/cluster.conf.example改为conf/cluster.conf,编辑文件:
192.168.1.5:8849
192.168.1.5:8850
192.168.1.5:8851
依次使用sh /bin/startup.sh
命令启动。
nginx配置:
events{}
http {
upstream nacos {
server 192.168.1.5:8849;
server 192.168.1.5:8850;
server 192.168.1.5:8851;
}
server {
listen 8848; #客户端访问地址
location / {
proxy_pass http://nacos;
}
}
}
输入http://192.168.1.5:8848 登录nacos,用户名nacos,密码nacos。
引入依赖:
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-nacos-discovery</artifactId>
</dependency>
加入注解:(以前低版本需要写,现在其实不需要)
package com.tuling;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@SpringBootApplication
@EnableDiscoveryClient //高版本可以不写
public class Tulingvip01MsAlibabaNacosClientOrderApplication {
public static void main(String[] args) {
SpringApplication.run(Tulingvip01MsAlibabaNacosClientOrderApplication.class, args);
}
}
写配置文件:
spring:
datasource:
druid:
username: root
password: 123456
jdbcUrl: jdbc:mysql://192.168.1.14:3306/tuling-ms-alibaba?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=UTF-8&useSSL=false
driverClassName: com.mysql.jdbc.Driver
initialSize: 5
minIdle: 5
maxActive: 20
maxWait: 60000
timeBetweenEvictionRunsMillis: 60000
minEvictableIdleTimeMillis: 300000
validationQuery: SELECT 1 FROM DUAL
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
poolPreparedStatements: true
filters: stat,wall #\u914D\u7F6E\u8FC7\u6EE4\u5668
maxPoolPreparedStatementPerConnectionSize: 20
useGlobalDataSourceStat: true
connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500
cloud:
nacos:
discovery:
server-addr: 192.168.1.5:8848
#环境隔离
namespace: 13499a23-e36e-41e7-8f8b-bd071bb8708e
#分组隔离
group: pay
#cluster不相同可以调到,但是优先调本集群
cluster-name: BJ
application:
name: order-center
server:
port: 8080
启动order-center和product-center服务,验证两个服务注册到nacos上:
order-center通过discoveryClient.getInstances
获取product-center服务信息,然后调用product-center去查询数据库信息,最后返回信息给客户端。
package com.tuling.controller;
import com.tuling.entity.OrderInfo;
import com.tuling.entity.ProductInfo;
import com.tuling.mapper.OrderInfoMapper;
import com.tuling.vo.OrderVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import java.util.List;
@RestController
public class OrderInfoController {
@Autowired
private RestTemplate restTemplate;
@Autowired
private OrderInfoMapper orderInfoMapper;
@Autowired
private DiscoveryClient discoveryClient;
@RequestMapping("/selectOrderInfoById/{orderNo}")
public Object selectOrderInfoById(@PathVariable("orderNo") String orderNo) {
OrderInfo orderInfo = orderInfoMapper.selectOrderInfoById(orderNo);
if(null == orderInfo) {
return "根据orderNo:"+orderNo+"查询没有该订单";
}
/**
* 从nacos server获取 product-info的地址
*/
List<ServiceInstance> serviceInstanceList = discoveryClient.getInstances("product-center");
if(null == serviceInstanceList || serviceInstanceList.isEmpty()) {
return "用户微服务没有对应的实例可用";
}
/**
* 获取第0个元素
*/
String targetUri = serviceInstanceList.get(0).getUri().toString();
ResponseEntity<ProductInfo> responseEntity= restTemplate.getForEntity(targetUri+"/selectProductInfoById/"+orderInfo.getProductNo(), ProductInfo.class);
ProductInfo productInfo = responseEntity.getBody();
if(productInfo == null) {
return "没有对应的商品";
}
OrderVo orderVo = new OrderVo();
orderVo.setOrderNo(orderInfo.getOrderNo());
orderVo.setUserName(orderInfo.getUserName());
orderVo.setProductName(productInfo.getProductName());
orderVo.setProductNum(orderInfo.getProductCount());
return orderVo;
}
@GetMapping("/getServiceList")
public List<ServiceInstance> getServiceList() {
List<ServiceInstance> serviceInstanceList = discoveryClient.getInstances("order-center");
return serviceInstanceList;
}
}
调用order-center接口查询订单信息: