一个简单的微服务系统:服务注册和发现,服务消费,负载均衡,断路器,智能路由,配置管理

服务注册中心:

  eureka是一个高可用组件,没有后端缓存,每一个实例注册后向注册中心发送心跳,默认情况下,erureka server也是一个eureka clinet,必须指定server

  引入依赖:

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka-server</artifactId>
        </dependency>

  启用注册中心:

@EnableEurekaServer
@SpringBootApplication
public class App 
{
    public static void main( String[] args )
    {
        SpringApplication.run(App.class, args);
    }
}

   YML配置:

server:
  port: 8761
  
spring:
  application:
    name: microservice-registry
  profiles:
    active: native

eureka:
  instance:
    prefer-ip-address: true
  client:
    registerWithEureka: false
    fetchRegistry: false
#serverUrl:
#  defaultZone: http://otherRegistry:port/eureka/

eureka客户端:

  依赖:

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
        </dependency>

  启动:

@SpringBootApplication
@EnableDiscoveryClient
@RestController
public class App 
{
       public static void main( String[] args )
       {
               SpringApplication.run(App.class, args);
       }
    
    @RequestMapping("/hi")
    public String home(@RequestParam String name) {
        return "hi "+name+",i am from port: " +port;
    }
}

  YML配置:

spring:
  application:
    name: microservice-producer
  profiles:
    active: native
 
eureka:
  instance:
    prefer-ip-address: true
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/

 

在微服务架构中,业务都会被拆分成一个独立的服务,服务与服务间基于http restful

springcloud有两种服务调用方式:ribbon+restTemplate和feign,ribbon是一个负载均衡客户端,可以很好控制http和tcp的一些行为,feign默认集成也ribbon

  ribbon+restTemplate:

    依赖:

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-ribbon</artifactId>
        </dependency>

    启动:

@SpringBootApplication
@EnableDiscoveryClient
public class App 
{
    public static void main( String[] args )
    {
        SpringApplication.run(App.class, args);
    }
    
    @Bean
    @LoadBalanced
    RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

  调用:

@Service
public class HelloService {

    @Autowired
    RestTemplate restTemplate;

    public String hiService(String name) {
        return restTemplate.getForObject("http://eureka-producer/hi?name="+name,String.class);
    }
    
}

  YML配置:

spring:
  application:
    name: microservice-ribbon-consumer
  profiles:
    active: native
 
eureka:
  instance:
    prefer-ip-address: true
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/   

  feign:

    依赖:

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-feign</artifactId>
        </dependency>

      启动:

@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class App 
{
    public static void main( String[] args )
    {
        SpringApplication.run(App.class, args);
    }
}

    调用:

@RestController
public class HiController {

    @Autowired
    SchedualServiceHi schedualServiceHi;
    @RequestMapping(value = "/hi",method = RequestMethod.GET)
    public String sayHi(@RequestParam String name){
        return schedualServiceHi.sayHiFromClientOne(name);
    }
}

@FeignClient(value = "eureka-producer")
public interface SchedualServiceHi {
    @RequestMapping(value = "/hi",method = RequestMethod.GET)
    String sayHiFromClientOne(@RequestParam(value = "name") String name);
}

    yml配置:

spring:
  application:
    name: microservice-feign-consumer
  profiles:
    active: native
    
eureka:
  instance:
    prefer-ip-address: true
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/

 

断路器:应付故障传播问题

  ribbon+restTemplate:

    依赖:

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-hystrix</artifactId>
        </dependency>

    启动:

@SpringBootApplication
@EnableDiscoveryClient
@EnableHystrix
public class App 
{
    public static void main( String[] args )
    {
        SpringApplication.run(App.class, args);
    }
    
    @Bean
    @LoadBalanced
    RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

      使用:

@Service
public class HelloService {

    @Autowired
    RestTemplate restTemplate;

    @HystrixCommand(fallbackMethod = "hiError")
    public String hiService(String name) {
        return restTemplate.getForObject("http://eureka-producer/hi?name="+name,String.class);
    }
    
    public String hiError(String name) {
        return "hi,"+name+",sorry,error!";
    }

}

      YML中不需要额外配置

  feign:

    依赖同上

    启动:

@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
@EnableCircuitBreaker
public class App 
{
    public static void main( String[] args )
    {
        SpringApplication.run(App.class, args);
    }
}

    使用:

@FeignClient(value = "eureka-producer", fallback = SchedualServiceHiHystric.class)
public interface SchedualServiceHi {
    @RequestMapping(value = "/hi",method = RequestMethod.GET)
    String sayHiFromClientOne(@RequestParam(value = "name") String name);
}


@Component
public class SchedualServiceHiHystric implements SchedualServiceHi {
    @Override
    public String sayHiFromClientOne(String name) {
        return "sorry "+name;
    }
}

     yml配置:

      额外添加:

feign:
  hystrix:
    enabled:true

 

路由网关:

  依赖:

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-zuul</artifactId>
        </dependency>

  启动:

@EnableZuulProxy
@EnableDiscoveryClient
@SpringBootApplication
public class App 
{
    public static void main( String[] args )
    {
        SpringApplication.run(App.class, args);
    }
}

  yml配置:

spring:
  application:
    name: microservice-gateway
  profiles:
    active: native
    
eureka:
  instance:
    prefer-ip-address: true
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/

zuul:
  routes:
    microservice-producer:
      path: /produce/**
      serviceId: microservice-producer

 

配置管理:

  服务器依赖:

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-config-server</artifactId>
        </dependency>

  客户端依赖:

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-config</artifactId>
        </dependency>

  服务器端启动:

@EnableDiscoveryClient
@SpringBootApplication
@EnableConfigServer
public class App 
{
    public static void main( String[] args )
    {
        SpringApplication.run(App.class, args);
    }
}

  客户端启动不需要额外添加

  服务器端yml配置:

server:
  port: 8000  
  
spring:
  application:
    name: microservice-config
  cloud:
    config:
      server:
        native:
          search-locations: classpath:/repo
  profiles:
    active: native

eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/

  客户端yml配置:

spring:
  application:
    name: microservice-gateway
  cloud:
    config:
      uri: http://localhost:8000
      fail-fast: true
  profiles:
    active: native
    
eureka:
  instance:
    prefer-ip-address: true
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/

 

监控管理:

  依赖:

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-turbine</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-netflix-turbine</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-hystrix-dashboard</artifactId>
        </dependency>

  启动:

@SpringBootApplication
@EnableTurbine
@EnableDiscoveryClient
@EnableHystrixDashboard
public class App 
{
    public static void main( String[] args )
    {
        SpringApplication.run(App.class, args);
    }
}

  yml配置:

server:
  port: 8770

security.basic.enabled: false

turbine:
  aggregator:
    clusterConfig: default   # 指定聚合哪些集群,多个使用","分割,默认为default。可使用http://.../turbine.stream?cluster={clusterConfig之一}访问
  appConfig: microservice-feign-consumer,microservice-ribbon-consumer  ### 配置Eureka中的serviceId列表,表明监控哪些服务
  clusterNameExpression: new String("default")
  # 1. clusterNameExpression指定集群名称,默认表达式appName;此时:turbine.aggregator.clusterConfig需要配置想要监控的应用名称
  # 2. 当clusterNameExpression: default时,turbine.aggregator.clusterConfig可以不写,因为默认就是default
  # 3. 当clusterNameExpression: metadata['cluster']时,假设想要监控的应用配置了eureka.instance.metadata-map.cluster: ABC,则需要配置,同时turbine.aggregator.clusterConfig: ABC

  

消息总线:将分布式节点用轻量的消息代理连接起来,可用于广播配置文件的更改或者服务之间的通讯,也可用于监控

    

  

  

posted on 2017-11-24 12:29  啊哈咧  阅读(240)  评论(0编辑  收藏  举报