Spring Cloud Alibaba 项目搭建
1.项目结构搭建
springcloudalibaba-xmn
pom.xml
gateway-server-1030 //网关
user-common //公共类
order-server-1020 //消费者服务
user-server-1010 //提供者服务
父工程搭建
pom.xml
<!--公共的一些配置-->
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<!--SpringBoot-->
<parent>
<groupId> org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.5.RELEASE</version>
</parent>
<!--SpringCloud-->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.2.1.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Hoxton.SR3</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
user模块的搭建:
pom.xml
<dependencies>
<!--公共类配置-->
<dependency>
<groupId>cn.xmn</groupId>
<artifactId>user-commom</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- nacaos 注册发现客户端 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- 配置中心客户端-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<!-- sentinel 客户端 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<!--Sentinel和Nacos做持久的-->
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
<version>1.5.2</version>
</dependency>
</dependencies>
user客户端主启动类
package cn.xmn;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@SpringBootApplication
@EnableDiscoveryClient
public class UserApplication {
public static void main(String[] args) {
SpringApplication.run(UserApplication.class);
}
}
user的yml配置文件
server:
port: 10010
spring:
application:
name: user-server
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848 #注册中心地址
启动Nacos,观察user是否注册进来
user的cotroller接口实现
package cn.xmn.controller;
import cn.xmn.pojo.User;
import cn.xmn.sentinelhandler.UserBlockHandler;
import cn.xmn.sentinelhandler.UserFallBack;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.concurrent.ThreadLocalRandom;
@RestController
@RefreshScope //刷新配置
@RequestMapping("/user")
public class UserController {
@Value("${server.port}")
private int port ;
@RequestMapping("/getuser/{id}")
@SentinelResource(value = "user-getUser",
blockHandler ="getUserBlockHandler",
blockHandlerClass = UserBlockHandler.class,
fallbackClass = UserFallBack.class,
fallback = "getUserFallBack"
)
public User getUser(@PathVariable("id") Long id){
int i = ThreadLocalRandom.current().nextInt(6);
System.out.println("i :" + i);
if (i%3 ==0){
int j = 1/0;
}
return new User(id,"九块九小码农",28,"java"+port);
}
}
UserBlockHandler
package cn.xmn.sentinelhandler;
import cn.xmn.pojo.User;
import com.alibaba.csp.sentinel.slots.block.BlockException;
public class UserBlockHandler {
//必须是静态方法
public static User getUserBlockHandler(Long id, BlockException e){
e.printStackTrace();
return new User(-1L,"限流了",500,"我被限流了");
}
}
UserFallBack
package cn.xmn.sentinelhandler;
import cn.xmn.pojo.User;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeException;
public class UserFallBack {
public static User getUserFallBack(Long id,DegradeException exception){
exception.printStackTrace();
return new User(-1L,"熔断降级",500,"出现异常,我被熔断了");
}
}
application.yml
#server:
# port: 10010
#
#spring:
# application:
# name: user-server
#
# cloud:
# nacos:
# discovery:
# server-addr: 127.0.0.1:8848
spring:
cloud:
sentinel: #sentinel仪表盘
transport:
dashboard: 127.0.0.1:1111
datasource:
flow:
nacos: #限流持久配置
server-addr: localhost:8848 #使用nacos的持久
dataId: user-sentinel #获取限流的数据源的dataId
groupId: DEFAULT_GROUP
rule-type: flow #类型:限流
namespace: 35bf3e12-6a2d-49f3-885d-517639e5afa5
bootstrap.yml
#server:
# port: 10020
spring:
application:
name: user-server #服务名称
cloud:
nacos:
config: # 配置中心
server-addr: 127.0.0.1:8848
file-extension: yaml
namespace: 35bf3e12-6a2d-49f3-885d-517639e5afa5 #命名空间
group: DEFAULT_GROUP
profiles:
active: dev
公共模块的搭建:
user-common的集成:
pom.xml
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
实体类
package cn.xmn.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private Long id;
private String name;
private Integer age;
private String info;
}
gateway模块的搭建:
pom.xml
<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>
<!-- 限流和gataway使用-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
</dependencies>
yml配置
server:
port: 10030
spring:
application:
name: gateway-server
cloud:
nacos:
discovery:
server-addr: 127.0.0.1:8848
sentinel: #sentinel仪表盘
transport:
dashboard: 127.0.0.1:1111
gateway:
discovery:
locator:
enabled: false #开放服务名访问方式
lower-case-service-id: true #服务名小写
routes:
- id: application-user #指定服务名
uri: lb://user-server #去注册中心找这个服务名
predicates: #断言,匹配访问的路径
- Path=/apis/user/** #服务访问路径
filters:
- StripPrefix=2 #请求转发的时候会去掉 /user访问路径
getway启动类:
package cn.xmn;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@SpringBootApplication
@EnableDiscoveryClient
public class GateWayApplication {
public static void main(String[] args) {
SpringApplication.run(GateWayApplication.class);
}
}
SentineConfig类集成
package cn.xmn.config;
import com.alibaba.csp.sentinel.adapter.gateway.sc.callback.BlockRequestHandler;
import com.alibaba.csp.sentinel.adapter.gateway.sc.callback.GatewayCallbackManager;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.reactive.function.server.ServerResponse;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
@Configuration
public class SentinelConfig {
public SentinelConfig(){
GatewayCallbackManager.setBlockHandler(new BlockRequestHandler() {
@Override
public Mono<ServerResponse> handleRequest(ServerWebExchange serverWebExchange, Throwable throwable) {
return ServerResponse.ok().body(Mono.just("限流啦,请求太频繁"),String.class);
}
});
}
}
order模块的搭建:
pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--nacos 注册中心客户端的包 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!--nacos 配置客户端的包 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<!--sentinel的集成feign的包-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
application.yml配置
##server:
## port: 10020
#
#
#spring:
# application:
# name: order-server
#
# cloud:
# nacos:
# discovery: # 注册中心的
# server-addr: 127.0.0.1:8848
#
# config: # 配置中心
# server-addr: 127.0.0.1:8848
# file-extension: yaml
# profiles:
# active: dev
feign:
sentinel:
enabled: true #熔断
bootstrap.yml配置:
#server:
# port: 10020
spring:
application:
name: order-server
cloud:
nacos:
discovery: # 注册中心的
server-addr: 127.0.0.1:8848
config: # 配置中心
server-addr: 127.0.0.1:8848
file-extension: yaml
profiles:
active: dev
主启动类
package cn.xmn;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class OrderApplication {
public static void main(String[] args) {
SpringApplication.run(OrderApplication.class);
}
}
controller层
package cn.xmn.controller;
import cn.xmn.feignclient.UserFeignClient;
import cn.xmn.pojo.User;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/order")
@Slf4j
@RefreshScope
public class OrderController {
@Autowired
private UserFeignClient feignClient;
@Value("${text.value}")
private String text;
@RequestMapping("/getuser/{id}")
public User getUser(@PathVariable("id") Long id){
// 调用UserServer的API -- Http
User user = feignClient.getUser(id);
log.info("text: "+text);
return user ;
}
}
UserFeignClient接口
package cn.xmn.feignclient;
import cn.xmn.feignclient.factory.UserFeignClientFallbackFactory;
import cn.xmn.pojo.User;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
@FeignClient(value = "user-server",fallbackFactory = UserFeignClientFallbackFactory.class)
public interface UserFeignClient {
@RequestMapping("/user/getuser/{id}")
User getUser(@PathVariable("id") Long id);
}
实现工厂类
package cn.xmn.feignclient.factory;
import cn.xmn.feignclient.UserFeignClient;
import cn.xmn.pojo.User;
import feign.hystrix.FallbackFactory;
import org.springframework.stereotype.Component;
@Component
public class UserFeignClientFallbackFactory implements FallbackFactory<UserFeignClient> {
@Override
public UserFeignClient create(Throwable throwable) {
throwable.printStackTrace();
return new UserFeignClient() {
@Override
public User getUser(Long id) {
return new User(-1L,"兜底数据+Sentinel",500,"我挂了");
}
};
}
}
2. Nacos管理
3.Sentinel限流和熔断
欢迎各位大佬多多指教,每天分享一些学习心得,充实每一天!