百度图片点击变网站是怎么做的怎么查看网站访问速度
web/
2025/10/6 19:36:08/
文章来源:
百度图片点击变网站是怎么做的,怎么查看网站访问速度,四川在线城市论坛,关键词自助优化原文#xff1a;https://www.liaoxuefeng.com/article/00151054582348974482c20f7d8431ead5bc32b30354705000在大型应用程序中#xff0c;配置主从数据库并使用读写分离是常见的设计模式。在Spring应用程序中#xff0c;要实现读写分离#xff0c;最好不要对现有代码进行改…原文https://www.liaoxuefeng.com/article/00151054582348974482c20f7d8431ead5bc32b30354705000在大型应用程序中配置主从数据库并使用读写分离是常见的设计模式。在Spring应用程序中要实现读写分离最好不要对现有代码进行改动而是在底层透明地支持。Spring内置了一个AbstractRoutingDataSource它可以把多个数据源配置成一个Map然后根据不同的key返回不同的数据源。因为AbstractRoutingDataSource也是一个DataSource接口因此应用程序可以先设置好key 访问数据库的代码就可以从AbstractRoutingDataSource拿到对应的一个真实的数据源从而访问指定的数据库。它的结构看起来像这样┌───────────────────────────┐│ controller ││ set routing-key xxx │└───────────────────────────┘│▼┌───────────────────────────┐│ logic code │└───────────────────────────┘│▼┌───────────────────────────┐│ routing datasource │└───────────────────────────┘│┌─────────┴─────────┐│ │▼ ▼┌─────────────┐ ┌─────────────┐│ read-write │ │ read-only ││ datasource │ │ datasource │└─────────────┘ └─────────────┘│ │▼ ▼┌─────────────┐ ┌─────────────┐│ │ │ ││ Master DB │ │ Slave DB ││ │ │ │└─────────────┘ └─────────────┘第一步配置多数据源首先我们在SpringBoot中配置两个数据源其中第二个数据源是ro-datasourcespring:datasource:jdbc-url: jdbc:mysql://localhost/testusername: rwpassword: rw_passworddriver-class-name: com.mysql.jdbc.Driverhikari:pool-name: HikariCPauto-commit: false...ro-datasource:jdbc-url: jdbc:mysql://localhost/testusername: ropassword: ro_passworddriver-class-name: com.mysql.jdbc.Driverhikari:pool-name: HikariCPauto-commit: false...在开发环境下没有必要配置主从数据库。只需要给数据库设置两个用户一个rw具有读写权限一个ro只有SELECT权限这样就模拟了生产环境下对主从数据库的读写分离。在SpringBoot的配置代码中我们初始化两个数据源SpringBootApplicationpublic class MySpringBootApplication {/*** Master data source.*/Bean(masterDataSource)ConfigurationProperties(prefix spring.datasource)DataSource masterDataSource() {logger.info(create master datasource...);return DataSourceBuilder.create().build();}/*** Slave (read only) data source.*/Bean(slaveDataSource)ConfigurationProperties(prefix spring.ro-datasource)DataSource slaveDataSource() {logger.info(create slave datasource...);return DataSourceBuilder.create().build();}...}第二步编写RoutingDataSource然后我们用Spring内置的RoutingDataSource把两个真实的数据源代理为一个动态数据源public class RoutingDataSource extends AbstractRoutingDataSource {Overrideprotected Object determineCurrentLookupKey() {return masterDataSource;}}对这个RoutingDataSource需要在SpringBoot中配置好并设置为主数据源SpringBootApplicationpublic class MySpringBootApplication {BeanPrimaryDataSource primaryDataSource(Autowired Qualifier(masterDataSource) DataSource masterDataSource,Autowired Qualifier(slaveDataSource) DataSource slaveDataSource) {logger.info(create routing datasource...);Map map new HashMap();map.put(masterDataSource, masterDataSource);map.put(slaveDataSource, slaveDataSource);RoutingDataSource routing new RoutingDataSource();routing.setTargetDataSources(map);routing.setDefaultTargetDataSource(masterDataSource);return routing;}...}现在RoutingDataSource配置好了但是路由的选择是写死的即永远返回masterDataSource现在问题来了如何存储动态选择的key以及在哪设置key在Servlet的线程模型中使用ThreadLocal存储key最合适因此我们编写一个RoutingDataSourceContext来设置并动态存储keypublic class RoutingDataSourceContext implements AutoCloseable {// holds data source key in thread local:static final ThreadLocal threadLocalDataSourceKey new ThreadLocal();public static String getDataSourceRoutingKey() {String key threadLocalDataSourceKey.get();return key null ? masterDataSource : key;}public RoutingDataSourceContext(String key) {threadLocalDataSourceKey.set(key);}public void close() {threadLocalDataSourceKey.remove();}}然后修改RoutingDataSource获取key的代码如下public class RoutingDataSource extends AbstractRoutingDataSource {protected Object determineCurrentLookupKey() {return RoutingDataSourceContext.getDataSourceRoutingKey();}}这样在某个地方例如一个Controller的方法内部就可以动态设置DataSource的KeyControllerpublic class MyController {Get(/)public String index() {String key slaveDataSource;try (RoutingDataSourceContext ctx new RoutingDataSourceContext(key)) {// TODO:return html... www.liaoxuefeng.com;}}}到此为止我们已经成功实现了数据库的动态路由访问。这个方法是可行的但是需要读从数据库的地方就需要加上一大段try (RoutingDataSourceContext ctx ...) {}代码使用起来十分不便。有没有方法可以简化呢有我们仔细想想Spring提供的声明式事务管理就只需要一个Transactional()注解放在某个Java方法上这个方法就自动具有了事务。我们也可以编写一个类似的RoutingWith(slaveDataSource)注解放到某个Controller的方法上这个方法内部就自动选择了对应的数据源。代码看起来应该像这样Controllerpublic class MyController {Get(/)RoutingWith(slaveDataSource)public String index() {return html... www.liaoxuefeng.com;}}这样完全不修改应用程序的逻辑只在必要的地方加上注解自动实现动态数据源切换这个方法是最简单的。想要在应用程序中少写代码我们就得多做一点底层工作必须使用类似Spring实现声明式事务的机制即用AOP实现动态数据源切换。实现这个功能也非常简单编写一个RoutingAspect利用AspectJ实现一个Around拦截AspectComponentpublic class RoutingAspect {Around(annotation(routingWith))public Object routingWithDataSource(ProceedingJoinPoint joinPoint, RoutingWith routingWith) throws Throwable {String key routingWith.value();try (RoutingDataSourceContext ctx new RoutingDataSourceContext(key)) {return joinPoint.proceed();}}}注意方法的第二个参数RoutingWith是Spring传入的注解实例我们根据注解的value()获取配置的key。编译前需要添加一个Maven依赖org.springframework.bootspring-boot-starter-aop到此为止我们就实现了用注解动态选择数据源的功能。最后一步重构是用字符串常量替换散落在各处的masterDataSource和slaveDataSource。使用限制受Servlet线程模型的局限动态数据源不能在一个请求内设定后再修改也就是RoutingWith不能嵌套。此外RoutingWith和Transactional混用时要设定AOP的优先级。本文代码需要SpringBoot支持JDK 1.8编译并打开-parameters编译参数。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/88079.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!