所需E币: 0
时间: 2023-12-21 16:08
大小: 3.22KB
目前主流的Java分布式框架有哪些,学起来难不难?Java的框架主要有:SpringMVC、Spring、Mybatis、Dubbo、Maven、RabbitMQ、Log4j、Ehcache、Redis、Shiro等等今天就给大家讲讲关于Java主流分布式的一些解决方法,内容包括:JVM锁和MySql锁解决库存超卖问题、基于Redisson框架实现分布式锁及实战&源码深入剖析、基于ZooKeeper实现分布式锁、分布式存储系统Etcd实现分布式锁、实现分布式锁通用SDK与集成、七种分布式事务解决方案、分布式事务Seata框架深入剖析、分库分表利器一-Sharding-JDBC实战等等内容。我将分别从源码、手撸框架、实战演练等多个方面进行多维度深入讲解,让大家轻松掌握分布式各种解决方案。首先我要问大家一个问题:大型项目分布式系统核心问题你能解决多少?1、分布式锁1.你知道Etcd如何实现分布式锁的吗?2.你知道Redis实现的分布式锁存在什么问题吗?3.不同分布式锁实现方案的优缺点你清楚了吗?4.如果让你手撸实现Redis分布式锁,你可以做到吗?2、分布式事务1.你知道为什么CAP不能同时满足吗?2.你了解不同分布式事务解决方案对应什么样的应用场景么?3.你知道为什么大多数业务场景都选择了最终一致性实现方案么?4.你了解Seata框架为什么当下如此受欢迎么?3、分布式ID1.这么多种分布式ID生成方式,应该选择哪种呢?2.雪花算法底层实现原理是什么?4、分库分表1.当数据量大了之后,我们应该如何选择分库分表的解决方案?2.做分库分表,是应该垂直切分还是水平切分?带着这些问题,我们一起来展开代码实战:新增和修改我们封装一个通用方法updateItem(),该方法传入两个参数:storeName、data,storeName表示对象仓库名称,data是一个对象,包含主键和索引,在调用indexedDB所提供的put()方法,在新增操作的时候不需要传入索引的键值对,修改操作的时候在该方法中另外多传递一个主键的键值对,这样才能根据id去修改对应的某一条数据。updateItem(storeName:string,data:any){ console.log(this.db) conststore=this.db.transaction([storeName],'readwrite').objectStore(storeName) constrequest=store.put({ ...data, updateTIme:newDate().getTime() }) request.onsuccess=(event:any)=>{ console.log('数据写入成功') console.log(event) } request.onerror=(event:any)=>{ console.log('数据写入失败') console.log(event) }}关键点是根据传入key即为主键id的值来查询某一条数据,需要使用到indexedDB提供的get()方法来实现查询操作。getItem(storeName:string,key:number|string){ conststore=this.db.transaction([storeName],'readwrite').objectStore(storeName) constrequest=store.get(key) request.onsuccess=(event:any)=>{ console.log('查询某一条数据成功') console.log(event.target.result) } request.onerror=(event:any)=>{ console.log('查询某一条数据失败') console.log(event) }}为了更好的获取indexedD事务中的返回结果,我们使用promise来包装一下上一小节indexedDB.ts中定义的几个方法:openStore、updateItem、deleteItem、getList、getItem。下面代码片段为getList() //查询所有数据 getList(storeName:string){ conststore=this.db.transaction(storeName).objectStore(storeName) constrequest=store.getAll() returnnewPromise((resolve,reject)=>{ request.onsuccess=(event:any)=>{ console.log('查询所有数据成功') console.log(event.target.result) resolve(event.target.result) } request.onerror=(event:any)=>{ console.log('查询所有数据失败') console.log(event) reject(event) } }) }在第一步中,首先使用Typescript的interface为store中的所有state声明类型,然后将interface放置在InjectionKeyd的泛型类型中,代码片段如下://src/store/index.tsimport{createStore,Store}from'vuex'import{InjectionKey}from'vue'//为storestate声明类型exportinterfaceAllStateTypes{ count:number, locale:any, userStatus:Number}//定义injectionkeyexportconstkey:InjectionKey<Store<AllStateTypes>>=Symbol('storeKey')exportconststore=createStore<AllStateTypes>({ //...})通过环境变量区分server.js中的一些代码片段,因为有些代码需要运行在开发环境,而有些代码需要运行在生产环境。本小节在server.js中一共对3个地方进行了环境区分,代码片段如下://server.jsif(!isProd){ //1.读取index.html template=fs.readFileSync( path.resolve(__dirname,'index.html'), 'utf-8' ) //2.应用ViteHTML转换。这将会注入ViteHMR客户端, // 同时也会从Vite插件应用HTML转换。 // 例如:@vitejs/plugin-react-refresh中的globalpreambles template=awaitvite.transformIndexHtml(url,template) //3.加载服务器入口。vite.ssrLoadModule将自动转换 // 你的ESM源码使之可以在Node.js中运行!无需打包 // 并提供类似HMR的根据情况随时失效。 render=(awaitvite.ssrLoadModule('/src/entry-server.ts')).render}else{ //1.读取index.html template=fs.readFileSync( path.resolve(__dirname,'dist/client/index.html'), 'utf-8' ) //3.加载服务器入口 render=require('./dist/server/entry-server.ts').render}fetchElephant()接口中有两个await,分别依次执行连接数据库和查询数据的操作,我们接下来在home.vue中引入这个Mock接口,然后调用,代码片段如下所示://home.vue//Mock接口functiongetElephant(){ fetchElephant().then(res=>{ console.log('Mock接口',res) })}getElephant()通过emit触发父组件上的事件,将language传递给父组件,并赋值给父组件中的全局组件<ElConfigProvider/>上的locale属性,同样也赋值给useI18n()实例上的locale属性,这样就可以实现在子组件headearCommon.vue中进行国际化切换操作并作用到父组件App.vue中