-
application.properties 配置 在application.properties 做相关配置。 在默认设置下,该服务注册中心也会将自己作为客户端来尝试注册它自己,所以我们需要禁用它的客户端注册行为
server.port=1111 #端口 eureka.client.register-with-eureka=false eureka.client.fetch-registry=false eureka.client.serviceUrl.defaultZone=http://localhost:${server.port}/eureka/
-
applicaiton 入口
@EnableEurekaServer //启动服务注册中心
@SpringBootApplication
public class RegisterApplication {
public static void main(String[] args) {
SpringApplication.run(RegisterApplication.class, args);
}
}
- POM 文件
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka-server</artifactId>
</dependency>
- 配置
#配置服务实例的名字,在后续的调用中,可以直接通过该名字对此服务进行访问
spring.application.name=compute-service
#指定服务实例的访问端口
server.port=2222
#指定要注册到上面的服务注册中心的位置
eureka.client.serviceUrl.defaultZone = http://localhost:1111/eureka/
- application.properties 配置文件
#配置服务实例的名字,在后续的调用中,可以直接通过该名字对此服务进行访问
spring.application.name=compute-service
#指定服务实例的访问端口
server.port=2222
#指定要注册到上面的服务注册中心的位置
eureka.client.serviceUrl.defaultZone=http://127.0.0.1:1111/eureka/
- Application 入口
@EnableDiscoveryClient //该注释能激活DiscoveryClient的实现,实现controller中的信息输出
@SpringBootApplication
public class ServiceApplication {
public static void main(String[] args) {
SpringApplication.run(ServiceApplication.class, args);
}
}
- POM 文件
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka-server</artifactId>
</dependency>
-
简介
- Ribbon是一个基于HTTP和TCP客户端的负载均衡器。
- Ribbon可以在通过客户端中配置的ribbonServerList服务端列表去轮询访问以达到均衡负载的作用。
- 当Ribbon与Eureka联合使用时,ribbonServerList会被DiscoveryEnabledNIWSServerList重写, 扩展成从Eureka注册中心中获取服务端列表。同时它也会用NIWSDiscoveryPing来取代IPing,它将职责委托给Eureka来确定服务端是否已经启动。
-
POM jar包
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-ribbon</artifactId>
</dependency>
- service代码
@Service
public class ComputeService {
@Autowired
RestTemplate template;
@HystrixCommand(fallbackMethod = "addServiceFallback") //开启熔断
public String addService() {
return template.getForEntity("http://COMPUTE-SERVICE/add?a=10&b=20", String.class).getBody();
}
public String addServiceFallback() {
return "error";
}
}
- Application 程序入口
@EnableDiscoveryClient //该注释能激活DiscoveryClient的实现,实现controller中的信息输出
@SpringBootApplication
@EnableCircuitBreaker //注解开启断路器功能:
public class ClientApplication {
@Bean
@LoadBalanced //负载均衡
RestTemplate restTemplate() {
return new RestTemplate();
}
public static void main(String[] args) {
SpringApplication.run(ClientApplication.class, args);
}
}
- appliaction.properties 配置文件
spring.application.name=ribbon-consumer
server.port=3333
eureka.client.serviceUrl.defaultZone=http://127.0.0.1:1111/eureka/
-
简介
- Feign是一个声明式的Web Service客户端,它使得编写Web Serivce客户端变得更加简单。
- 我们只需要使用Feign来创建一个接口并用注解来配置它既可完成。它具备可插拔的注解支持,包括Feign注解和JAX-RS注解
- Spring Cloud为Feign增加了对Spring MVC注解的支持,还整合了Ribbon和Eureka来提供均衡负载的HTTP客户端实现。
-
POM jar包
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
</dependency>
- 服务代码
@FeignClient(value="compute-service",fallback=ComputeClientHystrix.class) //fallback 熔断支持
public interface ComputeService {
@RequestMapping(method = RequestMethod.GET, value = "/add")
Integer add(@RequestParam(value = "a") Integer a, @RequestParam(value = "b") Integer b);
}
- Application 入口
@EnableDiscoveryClient //该注释能激活DiscoveryClient的实现,实现controller中的信息输出
@SpringBootApplication
@EnableFeignClients //@EnableFeignClients注解开启Feign功能,
public class FeignClientApplication {
public static void main(String[] args) {
SpringApplication.run(FeignClientApplication.class, args);
}
}
- application.properties 配置
pring.application.name=feign-consumer
server.port=3334
eureka.client.serviceUrl.defaultZone=http://127.0.0.1:1111/eureka/
-
简介
- Spring Cloud中使用了Hystrix 来实现断路器的功能。
- Hystrix是Netflix开源的微服务框架套件之一,该框架目标在于通过控制那些访问远程系统、服务和第三方库的节点,从而对延迟和故障提供更强大的容错能力。
- Hystrix具备拥有回退机制和断路器功能的线程和信号隔离,请求缓存和请求打包,以及监控和配置等功能。
-
在eureka-ribbon的主类RibbonApplication中使用@EnableCircuitBreaker注解开启断路器功能:
@SpringBootApplication
@EnableDiscoveryClient
@EnableCircuitBreaker
public class RibbonApplication {
@Bean
@LoadBalanced
RestTemplate restTemplate() {
return new RestTemplate();
}
public static void main(String[] args) {
SpringApplication.run(RibbonApplication.class, args);
}
}
- 在使用ribbon消费服务的函数上增加@HystrixCommand注解来指定回调方法。
@Service
public class ComputeService {
@Autowired
RestTemplate restTemplate;
@HystrixCommand(fallbackMethod = "addServiceFallback")
public String addService() {
return restTemplate.getForEntity("http://COMPUTE-SERVICE/add?a=10&b=20", String.class).getBody();
}
public String addServiceFallback() {
return "error";
}
}
-
说明
- Spring Cloud Config为服务端和客户端提供了分布式系统的外部化配置支持
- 配置服务器为各应用的所有环境提供了一个中心化的外部配置。
- Spring Cloud Config也提供本地存储配置的方式。
我们只需要设置属性spring.profiles.active=native,Config Server会默认从应用的src/main/resource目录下检索配置文件。
也可以通过spring.cloud.config.server.native.searchLocations=file:F:/properties/属性来指定配置文件的位置。
虽然Spring Cloud Config提供了这样的功能,但是为了支持更好的管理内容和版本控制的功能,还是推荐使用git的方式。
-
pom.xml中引入spring-cloud-config-server
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
- applicaiton 入口 @EnableConfigServer注解,开启Config Server
@EnableConfigServer
@SpringBootApplication
public class Application {
public static void main(String[] args) {
new SpringApplicationBuilder(Application.class).web(true).run(args);
}
}
- application.properties 中配置服务信息以及git信息
spring.application.name=config-server
server.port=7001
# git管理配置
spring.cloud.config.server.git.uri=http://git.oschina.net/didispace/SpringBoot-Learning/ #配置git仓库位置
spring.cloud.config.server.git.searchPaths=Chapter9-1-4/config-repo #配置仓库路径下的相对搜索位置,可以配置多个
spring.cloud.config.server.git.username=username
spring.cloud.config.server.git.password=password
-
验证
- URL与配置文件的映射关系如下:
- /{application}/{profile}[/{label}]
- /{application}-{profile}.yml
- /{label}/{application}-{profile}.yml
- /{application}-{profile}.properties
- /{label}/{application}-{profile}.properties
上面的url会映射{application}-{profile}.properties对应的配置文件,{label}对应git上不同的分支,默认为master
- pom 文件
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
- bootstrap.properties
#对应前配置文件中的{application}部分
spring.application.name=didispace
#对应前配置文件中的{profile}部分
spring.cloud.config.profile=prod
#对应前配置文件的git分支
spring.cloud.config.label=master
#配置中心的地址
spring.cloud.config.uri=http://localhost:7001/
注意:属性必须配置在bootstrap.properties中,因为config配置会先于application.properties。bootstrap 先于 application
- Controller 使用
后在需要自动更新配置变量的Java类上,使用注解 @RefreshScope 修饰。@Value 来获取值
@RefreshScope
@RestController
class TestController {
@Value("${from}")
private String from;
@RequestMapping("/from")
public String from() {
return this.from;
}
}
- Zuul的主要功能是路由和过滤器。路由功能是微服务的一部分。包括一下功能
- Authentication
- Insights
- Stress Testing
- Canary Testing
- Dynamic Routing
- Service Migration
- Load Shedding
- Security
- Static Response handling
- Active/Active traffic management
- pom 文件
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zuul</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
- application 入口
@EnableZuulProxy //注解开启Zuul
@SpringCloudApplication //整合了@SpringBootApplication、@EnableDiscoveryClient、@EnableCircuitBreaker
public class Application {
public static void main(String[] args) {
new SpringApplicationBuilder(Application.class).web(true).run(args);
}
@Bean
public AccessFilter accessFilter() {
return new AccessFilter();
}
}
- applicaiton.properties 配置文件
spring.application.name=api-gateway
server.port=5555
# routes to url
zuul.routes.api-a-url.path=/api-a-url/**
zuul.routes.api-a-url.url=http://localhost:2222/
zuul.routes.api-a.path=/api-a/**
zuul.routes.api-a.serviceId=service-A
zuul.routes.api-b.path=/api-b/**
zuul.routes.api-b.serviceId=service-B
eureka.client.serviceUrl.defaultZone=http://localhost:1111/eureka/
其中api-a-url 是自己定义的,可以随意。请求的话,是path -> url的映射。
- 服务过滤
- 在服务网关中定义过滤器只需要继承ZuulFilter抽象类实现其定义的四个抽象函数就可对请求进行拦截与过滤。
public class AccessFilter extends ZuulFilter{
private static Logger log = LoggerFactory.getLogger(AccessFilter.class);
@Override
public Object run() {
RequestContext ctx = RequestContext.getCurrentContext();
HttpServletRequest request = ctx.getRequest();
log.info(String.format("%s request to %s", request.getMethod(), request.getRequestURL().toString()));
Object accessToken = request.getParameter("accessToken");
if(accessToken == null) {
log.warn("access token is empty");
ctx.setSendZuulResponse(false);
ctx.setResponseStatusCode(401);
return null;
}
log.info("access token ok");
return null;
}
/**
* 返回一个boolean类型来判断该过滤器是否要执行,所以通过此函数可实现过滤器的开关。在上例中,我们直接返回true,所以该过滤器总是生效。
*/
@Override
public boolean shouldFilter() {
// TODO Auto-generated method stub
return true;
}
/**
* 通过int值来定义过滤器的执行顺序
*/
@Override
public int filterOrder() {
// TODO Auto-generated method stub
return 0;
}
/**
* pre:可以在请求被路由之前调用
routing:在路由请求时候被调用
post:在routing和error过滤器之后被调用
error:处理请求时发生错误时被调用
*/
@Override
public String filterType() {
return "pre";
}
}