jar 包
spring-cloud-starter-netflix-eureka-server
spring-boot-starter-security
jaxb-api
activation
jaxb-runtime
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-dependenciesartifactId>
<version> version>
<type>pomtype>
<scope>importscope>
dependency>
dependencies>
dependencyManagement>
main 类
@SpringBootApplication
@EnableEurekaServer
public class EurekaApp {
public static void main(String[] args){
SpringApplication.run(EurekaApp.class);
}
}
yml
server:
port: 8761
eureka:
client:
register-with-eureka: false
fetch-registry: false
service-url:
defaultZone: http://localhost:8761/eureka
enabled: true
spring:
security:
user:
name: user
password: 123
jar
spring-cloud-starter-netflix-eureka-client
org.springframework.cloud
spring-cloud-dependencies
pom
import
main 类
@SpringBootApplication
@EnableEurekaClient
public class ProviderUser
{
public static void main( String[] args )
{
SpringApplication.run(ProviderUser.class,args);
}
}
yml
server:
port: 7900 # 程序启动后的端口,也就是tomcat 的端口,我们可以自己定义
spring:
application:
name: provider-user # 应用别名
eureka:
client:
service-url:
defaultZone: http://user:123@localhost:8761/eureka
@GetMapping("/eurekainfo")
public String info(){
InstanceInfo instanceInfo = eurekaClient.getNextServerFromEureka("PROVIDER-USER",false);
return instanceInfo.getHomePageUrl();
}
得到url 地址 http://192.168.3.234:7900/
是消费者有多个,
在main 类前加@RibbonClient(“PROVIDER-USER”)
在controller 中
@GetMapping("/order/{id}")
public User getOrder(@PathVariable long id){
User user = restTemplate.getForObject("http://PROVEDER-USER/user/"+id, User.class);
return user;
}
yml
instance:
prefer-ip-address: true # 在eureka 中显示ip
@AutoWired
private LoadBalancerClient loadBalancerClient;
@GetMapping("/test")
public String test(){
ServiceInstance s = loadBalancerClient.choose("PROVIDER-USER"); // 查找对应服务的实例,会通过负载均衡算法查找
System.err.println("111"+s.getServiceId()+s.getHost()+":"+s.getPort());
return "1";
}
默认使用轮询
@SpringBootApplication
@EnableEurekaClient
@RibbonClient(name="PROVIDER-USER",configuration = TestConfig.class)// 不同的服务使用不同的负载均衡算法
在main 类上一级创建一个类,
@Configuration
public class TestConfig{
@AutoWired
IClientConfig clientConfig;
@Bean
public IRule ribbonRule(IClientConfig config){
return new RandomRule(); // 返回随机算法
}
也可以在main 类前
@ComponentScan(excludeFilters={@ComponentScan.Filter(type=FilterType.ANNOTATION,value = ExcludeCommentScan.class)}) // 只要main 类前加上这个就行了
自定义注解
public @interface ExcludeCommentScan{
}
然后在负载均衡算法类前加上@ExcludeCommentScan 就行了
PROVIDER-USER1: // 写服务的名字
ribbon:
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule # 给指定的服务配置负载均衡算法
ribbon:
eureka:
enabled: false # 在Eureka 中禁用ribbon, 禁用后需要自己负责负载均衡,不推荐
测试可以在hosts 文件中设置peer1 peer2 peer3 都为127.0.0.1
在application-peer3.yml中
defaultZone: http://peer2:8762/eureka/, http://peer1:8761/eureka
一个eureka 中有三个配置文件,然后在Run/Debug Configurations窗口左边有一个加号
选中spring boot , name peer1, Main class 选择三个配置文件的那个类,
Program arguments: --spring.profiles.active=peer1
就行了,然后创建peer2, peer3
然后这三个eureka 之间会相互注册,完全相同
jar: spring-cloud-starter-openfeign
main 前 @EnableFeignClients
在provider 中
@GetMapping("/get-user")
public User getUser(User user){
return user; // 自动获取id
}
在某个consumer 中
@FeignClient("provider-user")
public interface FeignClient01{
@GetMapping("/user/{id}") // C 版本不能使用getMapping
//@RequestMapping(value="/user/{id}", method=RequetMethod.GET)
User getOrder(@Param("id") Long id); // 使用RequestLine 时候, 必须添加@Param
@GetMapping("/get-user")// 这个和provider 中的url 相同, 无法访问
User get_user(User user); // 如果传递的是复杂参数,不管配置的是什么请求方式,都会以post
}
@RestController
public class OrderConteoller{
@AutoWired
private FeignClient01 feignClient01;
@GetMapping("/user/{id}")
User getOrder(@Param("id") Long id){
User user = Param.getOrder(id); // @Param
return user;
}
@GetMapping("get-user")
public User getOrder(User user){
User user = feignCliento1.get_user(user);
return user;
}
}
@FeignClient(name="provider-user", configuration=FeignClient01Config.class)
public interface FeignClient01{
@RequestLine("GET /user/{id}") //组合注解,第一个是请求方式,第二个是参数,空格分割
User getOrder(@PathVariable("id") long id);
@RequestLine("GET /get-user")
User get_user(User user);
}
@Configuration
public class FeignClient01Config{
@Bean
public Contract feignContract() {
return new feign.Contract.Default();
}
}
如果在FeignClient 中加上url 那么就不会通过找name来获取url 了, 直接使用给定的url
@FeignClient(name="dfdf" url="http://localhost:1000/", configuration= FeignClient02Config.class)
public interface FeignClient02{
@RequestMapping("/eureka/apps/{servicename}")
String getServiceInfo(@PathVariable("servicename") String servicename)
}
@RestController
public class OrderController{
@AutoWired
private FrignClient02 feignClient02;
@RequestMapping("/service/{name}")
public String getServiceInfo(@PathVariable String name){
return feignClient02.getServiceInfo(name);
}
}
指定用户名密码
@Configuration
public class FeignClient02Config{
@Bean // 配置用户名密码
public BasicAuthRequestInterceptor basicAuthRequestInterceptor(){
return new BasicAuthRequestInterceptor("user","123")
}
// 配置内容,必须在debug 才能输出
@Bean
Logger.Level feignLoggerLevel(){
return Logger.Level.FULL;
}
}
loggging:
level:
com.leiqingqi.springcloud.feign.FeignClient02:debug
jar spring-cloud-starter-netflix-hystrix
在main 类前添加@EnableCircuitBreaker
@RestController
public OrderController{
@AutoWired
private EurekaClient eurekaClient;
@GetMapping("/order/{id}") // 这样就在一个线程中了
@HystrixCommand(fallbackMethod = "shibai",commandProperties={
@HystrixProperty(name="execution.isolation.strategy",value="SEMAPHORE")})
public User getOrder(@PathVariable Long id){
InstanceInfo s = eurekaClient.getNextServerFromEureka("PROVIDER-USER", false);
String homePageUrl = instance.getHomePageUrl();
User user = restTemplate.getForObject(homePageUrl +"user" +id, User.class);
return user;
}
public User shibai(Long id){ // 默认这个和getOrder 不再一个线程
User user = new User(-100);
return user;
}
}
如果不加HystrixCommand, 那么出错后会出现失败页
circuit 关着是正常, 开启就是不正常
加@EnableCircuitBreaker 如果不加,如果一直请求不正常的,会一直请求,加了后,会熔断,(直接执行错误的方法)
feign:
hystrix:
enabled: true
@Component
public class FeignClient01Hytrix implements FeignClient01{
public User getOrder(long id){
User user = new User(-100);
return user;
}
public User get_user(User user){
return null;
}
}
@FrignClient(name="provider-user", fallback= FeignClient01HyStrix.class)
public interface FeignClient01{
}
在Feign config 中配置不使用Hytrix
只要加上这样一段代码就可以了
@Bean
@Scope("prototype")
public Feign.Builder feignBuilder(){
return Feign.builder();
}
@FeignClient(name="provider-user", fallbackFactory=FeignClient01Factory.class)
public interface FeignClient01{
}
@Component
public class FeignClient01Factory implements FallcackFacotry{
public FeignClient01 create(Throwable throwable){
return new FeignClient01(){
public User getOrder(Long id){
User user = new User(-100);
return user;
}
public User get_user(User user){
return user;
}
};
}
}
添加jar spring-cloud-starter-hystrix-dashboard
加注解 @EnableHystrixDashboard
然后 localhost:9900/hystrix, 在里面输入后缀为hystrix.stream 的url
jar spring-cloud-starter-netflix-turbine spring-cloud-starter-netflix-hystrix
main 类 注解 @EnableTurbine
yml
turbine:
aggregator:
clusterConfig: CONSUMER-ORDER-HYSTRIX
appConfig: consumer-order-hystrix
在localhost:9900/hystrix 中 输入192.168.3.234:8300/turbine.stream?cluster=CONSUMER-ORDER-HYSTRIX
turbine:
aggregator:
clusterConfig:default
appConfig:consumer-order-hystrix, consumer-order-feign-hystrix
cluster-name-expression: "'default'"
在localhost:9900/hystrix 中直接填写192.168.3.234:8300/turbine.stream
server:
context-path: /feignhystrix # 项目的访问路径
instance:
prefer-ip-address: true
home-page-url-path: /feignhyxtrix # 实力的home 地址多一块,如果我们是通过nginx 等反向代理的方式访问这个项目,而且反响代理的地址合当前的项目不一样,则需要使用url
turbine:
aggregator:
clusterConfig: CONSUMER-ORDER-FEIGN-HYSTRIX-TURBINE
appConfig: consumer-order-feign-hystrix-turbine
turbine.instanceUrlSuffix.CONSUMER-ORDER-FEIGN-HYSTRIX-TURBINE: /feignhyxtrix/hystrix.stream
在dashboard 上 访问 http://192.168.3.234:8300/turbine.stream?cluster=CONSUMER-ORDER-FEIGN-HYXTRIX-TURBINE
management port
eureka:
instance:
management.port: 8910
management:
port: 8910
我们使用这个获取服务,还是使用server: port 的 端口,但是想要管理,就使用8910
jar spring-cloud-starter-netflix-zuul spring-cloud-starter0netflix-eureka-client security
不添加security 的话,zuul 的路由页面无法访问
main 类
@SpringBootApplication
@EnableZuulProxy
然后访问这个url 192.168.3.234:10900/provider-user/user/1
就可以访问数据了
这个服务是从这个服务来的 192.168.3.234:7900/user/1
方法1
我们发现在url 中需要加入服务名称,有可能名称很长
zuul:
routes: # 配置路由映射
provider-user:/abc/ #给指定的服务做映射,比如当前是给provider-user 添加地址映射为/abc
可以使用这个url访问192.168.3.234:10900/abc/user/1
方法2
zuul:
routes: #配置路径映射
abcdef: #随便写,但是必须保证是唯一的
path: /abcd/** #映射的路径,也就是代理后的地址
serviceId: provider-user #给哪个服务做映射,这几行配置相当于前面的一行配置
方法3
zuul:
routes:
absdf:
path: /abcd/**
url: http://192.168.3.234:7900/ # 没有负载均衡
加入负载均衡
zuul:
routes:
absdf:
path: /abcd/**
serviceId: provider-user
ribbon:
eureka:
enabled: false # 在eureka 中禁用ribbon 的负载均衡
provider-user: # 给上面的serviceId 对应的服务的名字指定一个ribbon 的负载均衡,是从ListOfServers 配置的地址中选择
ribbon:
listOfServers: http://192.168.3.234:7900/, http://192.168.3.234:7901/
zuul能自动发现服务
zuul:
ignored-services: consumer-order # zuul 会从eureka 上找到素有注册的服务,然后全部做代理,如果我们不想要它代理,就这样做,以 逗号分隔
@Bean
public PatternServiceRouteMapper serviceRouteMapper(){
return new PatternServiceRouteMapper(
"(?^.+)-(?v.+$)" ,
"$(version)/$(name)");
}
zuul:
prefix: /suibian
然后进入 zuul 的url/routes, 显示所有url
在main 类前添加@EnableZuulProxy 启用zuul, 自带熔断和自动注册到eureka,
@Component
public class MyZuulFallback implements ZuulFallbackProvider{
public String getRoute(){
return "provider-user";
}
public ClientHttpResponse fallbackResponse(){
return new ClientHttpResponse(){
public HttpStatus getStatusCode() throws IOException{
retrun HttpStatus.BAD_PEQUEST;
}
public int getRawStatusCode() throws IOException{
return HttpStatus.BAD_REQUEST.value();
}
public String getStatusText() throws IOException{
return HttpStatus.BAD_REQUEST.getReasonPhrase();
}
public void close(){
}
public InputStream getBody() throws IOException{
return new ByteArrayInputStream(("出现错误"+ getRoute()).getBytes());
}
public HttpHeaders getHeaders(){
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setContentType(MediaType.APPLICATION_JSON);
RETURN httpHeaders;
}
};
}
}
加入sidecar jar 包, spring-cloud-netflix-sidecar
sidecar:
port: 9060
health-url:http://localohst:8060/health.json
main 类 @EnableSidecar
@component
public class MyPreZuulFilter extends ZuulFilter{
public String filterType(){
reutrn "pre";
}
public int filterOrder(){
return "1";
}
public boolean shouldFilter(){
return true;
}
public Object run(){
System.out.println("過濾器啓動了")
return null;
}
}
jar spring-cloud-config-server
git 上 spring-cloud-config 中有两个文件 application-yml foobar-dev.yml
server
spring:
cloud:
config:
server:
git:
url: http://gitee.com/jaskiechan/spring-cloud-config
# url: http://gitee.com/jaskiechan/{application} # 通过url 找仓库, 给不同的项目建立不同的仓库
spring:
cloud:
server:
git:
uri: https//gitee.com/jackiechan/spring-cloud-config # 默认配置
repos:
simple: # 当访问simple 的时候
uri: https://gitee.com/jackiechan/simple
special: # 当访问的是special 并符合以下规则的时候, 请求uri
pattern: special*/dev*, special*/test*
uri: https://gitee.com/jackiechan/special
spring:
cloud:
server:
git:
uri: https//gitee.com/jackiechan/spring-cloud-config # 默认配置
search-paths:
- abc # 以abc 开头的会被转到abc 目录
- def
clone-on-start: true # 启动就加载文件
# username: # 需要用户名密码的情况下设置
# password:
localhost:12900/master/abc-dev.properties
security:
basic:
enabled: true
user: # 加密码
password: 123
name:user
client
spring:
cloud:
config:
url: http://localhost:12900 #配置configserver 的地址, 配置server 相关的信息必须放到bootstrap.yml 中
profile: dev
label: master # 当使用git 的时候,lable 默认是master
application:
name: foobar # 代表找name+profile 对应的文件会找foorbar开头的dev 文件
bootstrap.yml
spring:
cloud:
config:
uri: http://localhost:12900 # 配置configserver 的地址,配置server 相关的信息必须放到bootstrap.yml中
profile: dev
label: master
discovery: # 发现的配置,原来是在application 中现在要配置的到这里
enabled: true
service-id: springcloud-config-client-eureka # 注册到eureka 的id
#username:# 如果configserver 需要用户名密码,
#password:
application:
name: foobar #代表要找 name+ profile 对应的文件, 会找foobar 开头的叫dev的文件
eureka:
client:
serviceUrl:
defaultZone: http://user:123@localhost:10000/eureka
使用rabbitmq
jar: spring-cloud-starter-bus-amqp
rabbitmq:
host: 192.168.3.233
post:5672
username: guest
password: guest