最近公司进行考核,其中就有搭建微服务并完成一些简单的业务,之前都是从git上拉一个,让我自己搭建还真是走了不少弯路。最后搭建起来回头看看也没有那么难
Nacos除了可以做注册中心,同样可以做配置管理来使用。
nacos需要安装,不理解nacos可以去官方了解和下载
nacos官网
Nacos是一个快速实现动态服务发现、服务配置、服务元数据及流量管理。
它其实就充当一个网关,可以将用户请求过滤以及修改然后再通过Getaway去转发到对应的请求服务上。(它本身也是一个服务,也要注册到nacos)
Gateway网关是我们服务的守门神,所有微服务的统一入口。
网关的核心功能特性:
权限控制:网关作为微服务入口,需要校验用户是是否有请求资格,如果没有则进行拦截。
路由和负载均衡:一切请求都必须先经过gateway,但网关不处理业务,而是根据某种规则,把请求转发到某个微服务,这个过程叫做路由。当然路由的目标服务有多个时,还需要做负载均衡。
限流:当请求流量过高时,在网关中按照下流的微服务能够接受的速度来放行请求,避免服务压力过大。
在SpringCloud中网关的实现包括两种:
Zuul是基于Servlet的实现,属于阻塞式编程。而SpringCloudGateway则是基于Spring5中提供的WebFlux,属于响应式编程的实现,具备更好的性能。
Feign是一个声明式的http客户端,官方地址:feign官网
作用就是帮助我们优雅的实现http请求的发送
SpringCloud微服务,虽然很多服务,但是服务之间使用的开发环境是相同的,所以Maven依赖也是有很多共同的。那么可以建一个父 Maven项目,然后配置依赖。在大项目中创建各个微服务项目。
pom内容
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.9.RELEASE</version>
<relativePath/>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<spring-cloud.version>Hoxton.SR10</spring-cloud.version>
<mysql.version>5.1.47</mysql.version>
<mybatis.version>2.1.1</mybatis.version>
</properties>
<dependencyManagement>
<dependencies>
<!-- springCloud -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--nacos的管理依赖-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.2.5.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- mysql驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
<!--mybatis-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>${mybatis.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
创建 application.properties并配置
server:
port: 8081
spring:
datasource:
url: jdbc:mysql://localhost:3306/cloud_user?useSSL=false
username: root
password: 123456
driver-class-name: com.mysql.jdbc.Driver
application:
name: userservice
cloud:
nacos:
server-addr: localhost:8848 # nacos服务地址
# discovery:
# namespace: 4d6ce343-9e1b-44df-a90f-2cf2b6b3d177 # dev环境
# ephemeral: false # 是否是临时实例
mybatis:
type-aliases-package: com.it.product.pojo
configuration:
map-underscore-to-camel-case: true
logging:
level:
com.it: debug
pattern:
dateformat: MM-dd HH:mm:ss:SSS
#eureka:
# client:
# service-url: # eureka的地址信息
# defaultZone: http://127.0.0.1:10086/eureka
userservice:
ribbon:
NFLoadBalancerRuleClassName: com.alibaba.cloud.nacos.ribbon.NacosRule # 负载均衡规则
ribbon:
eager-load:
enabled: true # 开启饥饿加载
clients: # 指定饥饿加载的服务名称
- productservice
feign:
httpclient:
enabled: true # 支持HttpClient的开关
max-connections: 200 # 最大连接数
max-connections-per-route: 50 # 单个路径的最大连接数
#main:
# allow-bean-definition-overriding: true # 一个服务只能用@FeignClient使用一次。现在可以使用多个
配置pom.xml
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!--mybatis-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>
<!-- nacos客户端依赖包 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!--feign客户端依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!--引入HttpClient依赖-->
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-httpclient</artifactId>
</dependency>
<!--引入feign的统一api-->
<dependency>
<groupId>com.it</groupId>
<artifactId>feign-api</artifactId>
</dependency>
<dependency>
<groupId>com.it</groupId>
<artifactId>feign-api</artifactId>
<version>1.0-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
<finalName>app</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
然后开始写业务代码…结构如图
然后启动user-server,看一看nacos注册上没有
nacos地址:localhost:8848 ,初始账号密码都是nacos。
同上我们创建product,这里就不在写了。注意端口号改一下**
这里配置都是一样的,只是user-service多了feign的依赖和feign.httpclient配置(因为我是用user-service去调用product服务的)
注意需要将feign抽取成一个独立的模块(松耦合)
userservice调用productservice的feign
/**
* 调用productservice的feign
*/
@FeignClient(value = "productservice")
public interface ProductClient {
/**
* 根据id查询角色
* @param roleId
* @return
*/
@GetMapping("/role/{roleId}")
Role findByRoleId(@PathVariable("roleId") Long roleId);
/**
* 根据id查询部门
* @param deptId
* @return
*/
@GetMapping("/dept/{deptId}")
Dept findByDeptId(@PathVariable("deptId") Long deptId);
}
注意这里pojo还要有被调用服务的实体类
pom文件
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
</dependencies>
注意user-service去远程调用productservice,要在user-service启动类加上
@EnableFeignClients(clients = ProductClient.class,defaultConfiguration = DefaultFeignConfiguration.class)
注解
也是作为一个独立的模块(需要启动类)
application.yml
server:
port: 10010
logging:
level:
cn.itcast: debug
pattern:
dateformat: MM-dd HH:mm:ss:SSS
spring:
application:
name: gateway
cloud:
nacos:
server-addr: localhost:8848 # nacos地址
gateway:
routes:
- id: user-service # 路由标示,必须唯一
uri: lb://userservice # 路由的目标地址
predicates: # 路由断言,判断请求是否符合规则
- Path=/user/** # 路径断言,判断路径是否是以/user开头,如果是则符合
- id: product-service
uri: lb://productservice
predicates:
- Path=/role/**
default-filters:
- AddRequestHeader=Truth,wwwwwwwwwwwwww! #添加请求头示例
pom文件 配置nacos服务注册依赖和网关依赖
<dependencies>
<!--nacos服务注册发现依赖-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!--网关gateway依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
</dependencies>
然后可以加一个全局过滤器(可以用于校验)
/**
* 自定义全局过滤器
*/
//@Order(-1) //优先级 数值越小 优先级越低
@Component
public class AuthorizeFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
// 1.获取请求参数
ServerHttpRequest request = exchange.getRequest();
MultiValueMap<String, String> params = request.getQueryParams();
// 2.获取参数中的 authorization 参数
String auth = params.getFirst("authorization");
// 3.判断参数值是否等于 admin
if ("admin".equals(auth)) {
// 4.是,放行
return chain.filter(exchange);
}
// 5.否,拦截
// 5.1.设置状态码
exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
// 5.2.拦截请求
return exchange.getResponse().setComplete();
}
@Override
public int getOrder() {
return -1;
}
}
其实上述代码就是,在请求的url后面需要加上authorization=admin才能放行
例如 localhost:10010/user/1?authorization=admin
到此,SpringBoot+SpringCloud+nacos+gateway+mybatis微服务就搭建完成了,开冲!