问题:配置在yml文件中的服务提供者的URL地址,如果服务提供者崩溃后,服务消费者future-order怎么能及时发现呢?
#这就是SpringCloud主要解决的问题,eureka提供服务注册功能,所有的服务都可以注册到eureka中,
#然后我们监控eureka的所有服务,一旦某个服务崩溃,可立即采取措施解决
2.1. 首先,将整个项目变成SpringCloud项目,在父项目futurecloud-master的pom.xml中添加SpringCloud的依赖
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>>Finchley.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
2.2. 创建一个SpringCloud的eureka项目:futurecloud-service,并添加eureka服务端的依赖
org.springframework.cloud spring-cloud-starter-netflix-eureka-server 2.1.1.RELEASE ************************************************************* 注意:从Finchley 开始,SpringCloud中的netflix家族组件,artifactId中新添加了netflix。 注册到eureka的服务,称为客户端,依赖的artifactId是spring-cloud-starter-netflix-eureka-client
2.3. 同时,对于服务端,客户端注册到服务端,为了安全,需要验证后才能注册,所以,我们需要在eureka服务端添加安全依赖
org.springframework.boot spring-cloud-starter-security ************************************************************* 2.4. 配置eureka server ************************************************************* server: port: 10000 spring: application: name: futurecloud-service eureka: client: register-with-eureka: false fetch-registry: false service-url: defaultZone: http://localhost:10000/eureka ************************************************************* 设置SpringApplication启动类,将此项目标记未eureka server ************************************************************* @SpringBootApplication @EnableEurekaServer //标记未eureka server public class EurekaServiceApplication { public static void main( String[] args )
{
SpringApplication.run(EurekaServiceApplication.class);
}
}
浏览器输入 http://localhost:10000/eureka ,到达eureka的登录界面,
此时的密码是eureka随机产生的,密码在eureka启动过程中的日志里面有输出
2.5. 配置eureka server 的登录密码
server:
port: 10000
eureka:
client:
register-with-eureka: false
fetch-registry: false
service-url:
defauleZone: http://user:123@localhost:10000/eureka
spring:
application:
name: futurecloud-service
security:
basic:
enabled: true #开启安全配置,也就是需要密码,如果不需要设置为false即可,注意,这个参数必须放在application.yml中,不允许放在bootstrap.yml中
user:
name: user
password: 123 #在配置了用户名和密码后,我们可以修改地址的访问风格为curl风格,http://user:123@localhost:10000/eureka
2.6. 将客户端futurecloud-user、futurecloud-order注册到eureka中
2.6.1. 在futurecloud-user、futurecloud-order中添加依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
<version>2.0.2.RELEASE</version>
</dependency>
<!--添加安全认证依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
2.6.2. 将futurecloud-user、futurecloud-order注册到eureka服务上
server:
port: 7900 #程序启动端口,也就是tomcat的端口
spring:
application:
name: futurecloud-user #应用名称,别名
#将此服务注册到eureka 服务上
eureka:
client:
service-url:
defaultZone: http://user:123@localhost:10000/eureka
futurecloud-order 相同配置
2.6.3. 将futurecloud-user、futurecloud-order声明为eureka 客户端
@SpringBootApplication
@EnableEurekaClient //声明为eureka 客户端
public class OrderApplication
{
@Bean //相当于xml中的bean标签,主要是用于调用当前方法获取到指定对象
public RestTemplate getRestTemplate(){
return new RestTemplate();
}
public static void main( String[] args )
{
SpringApplication.run(OrderApplication.class);
}
}
###############################
@SpringBootApplication
@EnableEurekaClient //声明为eureka 客户端
public class UserApplication {
public static void main( String[] args )
{
SpringApplication.run(UserApplication.class);
}
}
Spring Cloud 2.0以上,当eureka 服务端开启登录验证时,security默认启用了csrf检验,要在eurekaServer端配置security的csrf检验为false
解决方法
在eureka server项目上添加一个继承 WebSecurityConfigurerAdapter 的类;
在类上添加 @EnableWebSecurity 注解;
覆盖父类的 configure(HttpSecurity http) 方法,关闭掉 csrf
示例代码
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable(); //关闭csrf
http.authorizeRequests().anyRequest().authenticated().and().httpBasic(); //开启认证
}
}
#四、问题3: 采用eureka 服务端和客户端的方式,将服务都注册到eureka 服务端,但是,怎么使用呢?
通过一个接口EurekaClient,可以拿到注册到eureka 服务端的eureka客户端服务实例,如下代码实例:
@Autowired
private EurekaClient eurekaClient;
@GetMapping("/eureka/serverInfo")
public String serverInfo() {
//futurecloud-user 是spring 应用别名,配置在application.yml中
InstanceInfo instance = eurekaClient.getNextServerFromEureka(“futurecloud-user”, false);
return instance.getHomePageUrl();
}
通过EurekaClient能拿到注册到eureka服务端的服务实例后,消费者调用提供者的url,就可以通过EurekaClient找到提供者的url
提供者的url就不用写死在yml配置文件汇中了,如下futurecloud-order项目中,通过EurekaClient找到提供者futurecloud-user的url
@RestController
public class OrderController {
@Autowired
private RestTemplate restTemplate; //spring 提供的一个用于访问rest接口的模板对象
@Autowired
private EurekaClient eurekaClient;
// private String url = “http://localhost:7900/user/”; //获取服务提供者Url方式1:直接写死
// @Value("${user.url}") //获取服务提供者Url方式2:将url写到yml配置文件中
private String url;
@GetMapping("/order/{id}")
public User getOrder(@PathVariable Long id){
//futurecloud-user 是spring 应用别名,配置在application.yml中
InstanceInfo instance = eurekaClient.getNextServerFromEureka("FUTURECLOUD-USER", false);
url = instance.getHomePageUrl(); //获取服务提供者Url方式3:通过获取注册到eureka服务上的服务实例,获取服务提供者的url
//访问提供者,获取数据
//通过防伪rest,获取到Json数据,然后转换成User对象
User user = restTemplate.getForObject(url + "/user/" + id,User.class);
return user;
}
}
2.7. 将注册到eureka 上的服务地址转换成真实的Ip地址,只需要将注册在eureka服务的项目中添加配置prefer-ip-address: true
server:
port: 10000
eureka:
client:
register-with-eureka: false
fetch-registry: false
service-url:
defauleZone: http://user:123@localhost:10000/eureka
instance:
prefer-ip-address: true #将注册到eureka服务的实例使用ip地址