SpringCloud.md

  1. eureka

jar 包

spring-cloud-starter-netflix-eureka-server
spring-boot-starter-security
jaxb-api
activation
jaxb-runtime
<dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>             </version>
                <type>pom</type>
                <scope>import</scope>
            </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

<dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>             </version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

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

eurekaClient。getNextServerFromEureka

@GetMapping("/eurekainfo")
    public String info(){
        InstanceInfo instanceInfo = eurekaClient.getNextServerFromEureka("PROVIDER-USER",false);
        return instanceInfo.getHomePageUrl();
    }

得到url 地址 http://192.168.3.234:7900/

ribbon

是消费者有多个,

在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

LoadBalancerClient

@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";
}

默认使用轮询

自定义ribbon 算法

@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 就行了

配置文件方式

yml

PROVIDER-USER1:  // 写服务的名字
	ribbon:
		NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule # 给指定的服务配置负载均衡算法
		
		
ribbon:
	eureka: 
		enabled: false # 在Eureka 中禁用ribbon, 禁用后需要自己负责负载均衡,不推荐

多个eureka

测试可以在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 之间会相互注册,完全相同

feign

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;
    }
    
}

config

@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();
    }
    
}

url

如果在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
		

hystrix

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 关着是正常, 开启就是不正常

feign 整合

加@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();
}

fallbackFactory

@FeignClient(name="provider-user", fallbackFactory=FeignClient01Factory.class)
public interface FeignClient01{
    
}
@Component
public class FeignClient01Factory implements FallcackFacotry<FeignClient01>{
    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;
            }
        };
    }
}

Hystrix Dashboard

添加jar spring-cloud-starter-hystrix-dashboard

加注解 @EnableHystrixDashboard

然后 localhost:9900/hystrix, 在里面输入后缀为hystrix.stream 的url

turbine

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

zuul

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 上找到素有注册的服务,然后全部做代理,如果我们不想要它代理,就这样做,以  逗号分隔

将版本号放进url 中

@Bean
public PatternServiceRouteMapper serviceRouteMapper(){
    return new PatternServiceRouteMapper(
        "(?<name>^.+)-(?<version>v.+$)",
        "$(version)/$(name)");
    
}

加前缀

zuul:
	prefix: /suibian

然后进入 zuul 的url/routes, 显示所有url

zuul fallback

在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

加入sidecar jar 包, spring-cloud-netflix-sidecar

sidecar:
	port: 9060
		health-url:http://localohst:8060/health.json

main 类 @EnableSidecar

ZuulFilter

@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;
    }
}

ConfigServer

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 文件

配置到eureka 上面

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
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值