构建SpringBoot基本框架(下篇)

四、Spring Boot集成JTA事物
    如上,配置了多个数据源后,如果一个service方法存在多个数据源,使用jdbc事物不能实现整个方法的回滚操作。这时候需要使用另外一个一种事物管理框架JTA事物。它可以跨数据库来保证数据有效性。当然Spring Boot集成它也比较方便。
DataSourceTransactionManager.java
@Configuration
@ComponentScan
@EnableTransactionManagement //自动开启事物管理
public class DataSourceTransactionManager {

    /**
     * 自定义事务
     * MyBatis自动参与到Spring事务管理中,无需额外配置,只要org.mybatis.spring.SqlSessionFactoryBean引用的数据源与DataSourceTransactionManager引用的数据源一致即可,否则事务管理会不起作用。
     * @return
     */
    @Bean(name = "userTransaction")
    public UserTransaction userTransaction() throws Throwable {
        UserTransactionImp userTransactionImp = new UserTransactionImp();
        userTransactionImp.setTransactionTimeout(10000);
        return userTransactionImp;
    }

    @Bean(name="userTransactionManager", destroyMethod = "close", initMethod = "init")
    public UserTransactionManager userTransactionManager() {
        UserTransactionManager userTransactionManager = new UserTransactionManager();
        userTransactionManager.setForceShutdown(false);
        return userTransactionManager;
    }

    @Bean(name = "transactionManager")
    @DependsOn({ "userTransaction", "userTransactionManager" })
    public JtaTransactionManager transactionManager() throws Throwable {
        UserTransaction userTransaction = userTransaction();
        JtaTransactionManager manager = new JtaTransactionManager(userTransaction,userTransactionManager());
        return manager;
    }

}
开发单元测试验证下:
MultiDataBaseService.java
protected final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private PersonService personService;

    @Transactional
    public void handleInMultiDataBase(){

        Person person = new Person();
        person.setBirthDate(new Date());
        person.setFirstName("tian");
        person.setLastName("dd");
        person.setPhoneNo("222");
        person.setSex('F');

        personService.insertPerson(person);

        Person p = personService.getPersonById(1);
        logger.info("handleInMultiDataBase p={}", JSON.toJSONString(p));

        throw new RuntimeException("测试多数据源数据处理异常事物回滚");

    }
PersonServiceTest.java
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class PersonServiceTest{

    @Autowired
    MultiDataBaseService multiDataBaseService;

    @Test
    public void testInsertPerson(){

        Person person = new Person();
        person.setBirthDate(new Date());
        person.setFirstName("tian");
        person.setLastName("dd");
        person.setPhoneNo("111");
        person.setSex('F');

        personService.insertPerson(person);
    }
}
通过测试方法发现本条记录并没有插入到主数据库中,说明JTA事物配置成功。
五、Spring Boot监控搭建&编译&部署
  添加POM
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
Spring Boot会自动监控系统属性。当然我们也可以自定义一些监控项目。
HealthCheck.java
@Component
public class HealthCheck implements HealthIndicator{

    @Override
    public Health health() {
        //自定义监控项目,实际情况扩充...
        return Health.up().withDetail("health_check", true).build();
    }
}
编译&部署使用如下命令即可:
mvn clean package -Dskiptests
java -jar target/spring-boot.jar --spring.profiles.active=test
#根据系统环境有dev/test/prod
服务启动成功后,就可以直接访问接口了。如Controller层代码如下:
PersonController.java
@RestController
@EnableAutoConfiguration
public class PersonController {

    @Autowired
    private PersonService personService;
   
    @RequestMapping("/person/getPersonById")
    @ResponseBody
    public JsonResult getPersonById(@RequestParam("id") Integer id){
        return new JsonResult(personService.getPersonById(id));
    }
}
服务配置如下:
#配置监控项
server:
  port: 8082
management:
  port: 9999
  health:
    mail:
      enabled: false
  security:
    enabled: false

info:
  app:
    name: "@project.name@"
    description: "@project.description@"
    version: "@project.version@"
curl 'http://localhost:8082/person/getPersonById?id=11'
{
  code: "200",
  message: "成功",
  data: {
    id: 11,
    firstName: "tian",
    lastName: "dd_slave",
    birthDate: 1510243200000,
    sex: "F",
    phoneNo: "111"
        }
}

curl 'http://localhost:9999/health'
{
  status: "UP",
  healthCheck: {
  status: "UP",
  health_check: true
},
diskSpace: {
  status: "UP",
  total: 120108089344,
  free: 56391913472,
  threshold: 10485760
},
  db: {
   status: "UNKNOWN" 
  }
}
可以看到系统自定义的监控检查项也返回了。当然Spring Boot健康检查项还有很多API接口,如:info,beans,error等
Spring Boot集成Spring Boot Admin
一、创建服务端
    新建立Spring Boot工程,添加如下POM:
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-server</artifactId>
<version>1.5.2</version>
</dependency>
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-server-ui</artifactId>
<version>1.5.2</version>
</dependency>
配置文件:
spring:  
  application:  
    name: spring-boot-admin
  boot:  
    admin:  
      context-path: /sba    # 配置访问路径为:http://localhost:8888/spring-boot-admin/sba
      notify:
        mail:
          to: example@example.com
  mail:
    host: smtp.example.com

server:  
  port: 8888
  context-path: /spring-boot-admin/ #统一为访问的url加上一个前缀
启动类:
@SpringBootApplication
@EnableScheduling
@EnableAdminServer //一定要加上
public class SpringBootAdminApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootAdminApplication.class, args);
}
}
二、配置客户端
添加POM:
<dependency>  
    <groupId>de.codecentric</groupId>  
    <artifactId>spring-boot-admin-starter-client</artifactId>  
    <version>1.5.2</version>  
</dependency>  
配置:
spring:
  profiles:
    active: dev
  boot:
    admin:
      client:
        prefer-ip: true
      url: http://localhost:8888/spring-boot-admin # 向服务端注册的地址

先后启动服务端和客户端后,访问http://localhost:8888/spring-boot-admin/sba链接可查看到被监控的Spring Boot微服务。



可以通过这个平台监控系统基本属性&方法调用次数,执行时长&日志&请求Trace等等。当然也可以配置发送邮件模块、集群配置等。
参考资料
  http://projects.spring.io/spring-boot
   http://codecentric.github.io/spring-boot-admin/1.5.2/#register-clients-via-spring-boot-admin

本文来自网易实践者社区,经作者田躲躲授权发布。