1.安装sts(spring tool suite)
1.安装后项目前有[boot],yml文件中编码会有提示,不可不用
安装参考:
http://www.itxxz.com/a/gaoji/2015/0120/eclipse_spring_tools.html
2.springboot中,最方便的是配置了热部署
<!-- 热部署 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
部署后项目前有[devtools],修改无需重启
3.boot封装了json,返回的对象都是json格式
2.依赖和集成
1.查看eureka依赖树,euraka下有ribbon
eureka搭建完成后可以使用如下url查看
http://172.x.x.x:9080/eureka/apps
http://172.x.x.x:9080/eureka/apps/service-name
2.feign下有ribbon和hystrix,已经集成,只需要在feign中配置fallback即可
3.自定义封装
可以是重复的类,也可是重复的feign接口
4.ribbon默认的负载均衡策略
默认是轮询测略,可自定义为随机策略
microservice-provider: ##config ribbon
ribbon:
eureka:
enabled: false
listOfServers: localhost:8000, localhost:8002,localhost:8003 #假设provider有3台instance端口分别是8000 8002 8003
ServerListRefreshInterval: 15000 #设置服务列表刷新时间间隔
注意:
1.自定义配时,@Configuration包和@ComponentsScan包不应重叠
2.使用RestTemplate时,想要获得一个List时,应使用数组,而不应该直接使用List
5.feign集成了ribbon和hystrix
1.feign是webservice的客户端,
2.默认@FeignClient(name=”“)不写默认为name,
不建议用service-id,看源码知过时了,
@Deprecated String serviceId() default "";
其中参数还有个属性为url,注意有url时必须有name
最重要的话: (官文原话)
– springcloud根据需要使用FeignClientConfiguration为每个命名的客户端创建一个新的整体作为ApplicationContext.包含feign Decoder,feign Encoder,feign Contract
– 即@FeignClient(“”)创建了一个子容器 ,包含日志,解码器,编码器,契约(是springmvcContract,故可以支持mvc注解)
3.有6个坑:
3.1.接口中的方法必须用@RequestMapping(value= method=…),不能使用@GetMaping(不支持),否则无法启动
3.2.接口中的方法中往往有参数,一定不能省了@PathVariable(“”)设置value,否则报参数为0
3.3.接口中的方法中参数如果是对象,只能设置为Post方法,设置为get方法报错:需要get方法,即使你设置的就是get.
如果一定要用get,只能将对象属性全设置为参数,使用@RequestParam(“id”) int id,@RequestParam(“name”) string name…
3.4.在controller类中的注解上,如果不使用thymeleaf,则可用@RestController,对应方法上使用@GetMapping、@PostMapping;
如果使用thymeleaf,必须用@Controller,对应@RequestMaping…否则返回无法跳转到页面,只会返回对象
3.5.使用@Configuration时不要同时注解@ComponentsScan,有冲突
3.6 .启动应用报timeout错误时配置:
解决第一次请求报错超市异常(ms) hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds: 5000 或者 hystrix.command.default.execution.timout.enabled: false
6.自定义feign
使用@FeignClient的configuration属性,指定feign的配置类:
@FeignClient(name = "microservice-provider-user", configuration = FeignConfiguration.class) public interface UserFeignClient { /** * 使用feign自带的注解@RequestLine * @see https://github.com/OpenFeign/feign * @param id 用户id * @return 用户信息 */ @RequestLine("GET /{id}") public User findById(@Param("id") Long id); }
注意其中的注解格式,然后是配置类:
/** * 该类为Feign的配置类 * 注意:该不应该在主应用程序上下文的@ComponentScan中。 */ @Configuration public class FeignConfiguration { /** * 将契约改为feign原生的默认契约。这样就可以使用feign自带的注解了。 * @return 默认的feign契约 */ @Bean public Contract feignContract() { return new feign.Contract.Default(); } }
目录结构为:
上面的方式只是为UserFeignClient 接口设置了feign的配置类,如果还有其他的接口怎么办?
目前的方法是创建第二个接口类,对应设置第二个配置类。
feign的功能很多:
1.压缩GZIP:
feign.compression.request.enabled=true
feign.compression.response.enabled=true
2.日志: yml中配置,使用接口类全类名:
logging: level: com.xx.UserFeignClient: DEBUG
同时在配置类中添加,四个级别NONE,BASIC,HEADERS,FULL
@Configuration public class FooConfiguration { @Bean Logger.Level feignLoggerLevel() { return Logger.Level.FULL; } }
更多功能看官文
详细https://github.com/OpenFeign/feign和
cloud文档http://cloud.spring.io/spring-cloud-static/Dalston.SR1/
7.eureka常见问题
7.1 eureka界面的enviroment和datacenter配置
eureka: enviroment: product #eureka中环境 datacenter: cloud #eureka中datacenter,使用cloud,这样eureka将会知道是在AWS云上
7.2 eureka的自我保护提示
eureka的自我保护模式主要用于在一组客户端和eureka服务器之间存在网络分区的情况下的保护,在这些情况下,服务器尝试保护其已有的信息。就是说即使某个服务停止了,注册中心依然不剔除它。但是在开发阶段,这个不是我们需要的。
注意的是使用sts,则保护模式会失效,因为在点击停止的时候,sts会调用springboot的shundown hook,这个钩子会向eureka server主动下线。
如果要配置关闭自我保护,如下:
server端: eureka.server.enable-self-preservation #设为false,关闭自我保护模式 eureka.server.eviction-interval-timer-in-ms #清理间隔(ms,默认60*1000) client端: eureka.client.healthcheck.enabled = true #开启健康检查(actuator) eureka.instance.lease-renewal-interval-in-seconds=10 #租期更新时间间隔(默认30s) eureka.instance.lease-expiration-duration-in-seconds =30 #租期到期时间(默认90s)
示例如下:
eureka: instance: ip-address: 172.x.x.x prefer-ip-address: true lease-renewal-interval-in-seconds: 10 # 租期更新时间间隔(默认30s) lease-expiration-duration-in-seconds: 30 #租期到期时间(默认90s) client: serviceUrl: defaultZone: http://172.x.x.x:9079/eureka/ register-with-eureka: true fetch-registry: true healthcheck: enabled: true #开启健康检查(actuator) server: enable-self-preservation: false #设为false,关闭自我保护模式 eviction-interval-timer-in-ms: 4000 #清理间隔(ms,默认60*1000)
注意
1.更改eureka更新频率将打破服务器的自我保护功能
2.生产阶段不要更改eureka的配置,否则保护模式失效
8.feign的hystrix支持
Hystrix支持回退的概念:当断路器打开或者出现错误时执行的默认代码路径,要为给定的@FeignClient启用回退,请将fallback属性设置为实现回退的类名。
全局打开或禁用hystrix:
feign.hystrix.enabled = false
前面提到feign下集成有ribbon和hystrix,已经集成,只需要在feign中配置fallback即可
/** * Feign的fallback测试 * 使用@FeignClient的fallback属性指定回退类 */ @FeignClient(name = "microservice-provider-user", fallback = FeignClientFallback.class) public interface UserFeignClient { @RequestMapping(value = "/{id}", method = RequestMethod.GET) public User findById(@PathVariable("id") Long id); } /** * 回退类FeignClientFallback需实现Feign Client接口 * FeignClientFallback也可以是public class,没有区别 */ @Component class FeignClientFallback implements UserFeignClient { @Override public User findById(Long id) { User user = new User(); user.setId(-1L); user.setUsername("默认用户"); return user; } }
注意使用@Component时,不用配@ComponentScan,启动类有集成
怎样禁用单个FeignClient的Hystrix?
如同上面提到的,当有多个FeignClient接口类,怎么禁用某个的hystrix呢?
在configuration类中加入:
@Bean @Scope("prototype") public Feign.Builder feignBuilder(){ return Feign.builder(); }
之所以可以如此是因为
Feign.Builder feignBuilder: HystrixFeign.Builder
默认就是使用Feign.Builder 支持hystrixFeign。
9.feign的hystrix fallbacks
如果你需要在触发fallback触发器时返回一个错误原因,你可以使用fallbackFactory:
@FeignClient(name = "microservice-provider-user", fallbackFactory = FeignClientFallbackFactory.class) public interface UserFeignClient { @RequestMapping(value = "/{id}", method = RequestMethod.GET) public User findById(@PathVariable("id") Long id); } /** * UserFeignClient的fallbackFactory类,该类需实现FallbackFactory接口,并覆写create方法 */ @Component class FeignClientFallbackFactory implements FallbackFactory<UserFeignClient> { private static final Logger LOGGER = LoggerFactory.getLogger(FeignClientFallbackFactory.class); @Override public UserFeignClient create(Throwable cause) { return new UserFeignClient() { @Override public User findById(Long id) { // 日志最好放在各个fallback方法中,而不要直接放在create方法中。 // 否则在引用启动时,就会打印该日志。 // 详见https://github.com/spring-cloud/spring-cloud-netflix/issues/1471 FeignClientFallbackFactory.LOGGER.info("fallback; reason was:", cause); User user = new User(); user.setId(-1L); user.setUsername("默认用户"); return user; } }; } }