Rumah  >  Artikel  >  Java  >  Amalan mikroperkhidmatan Spring Cloud untuk melaksanakan kunci teragih

Amalan mikroperkhidmatan Spring Cloud untuk melaksanakan kunci teragih

王林
王林asal
2023-06-22 23:28:38775semak imbas

Dengan populariti seni bina perkhidmatan mikro, semakin banyak pasukan pembangunan perusahaan mula menggunakan Spring Cloud untuk membina sistem perkhidmatan mikro mereka sendiri. Dalam persekitaran teragih, melaksanakan kunci teragih ialah cabaran teknikal yang penting. Artikel ini akan memperkenalkan cara melaksanakan amalan mikroperkhidmatan kunci teragih di bawah rangka kerja Awan Musim Bunga.

Pertama sekali, kita perlu memahami apa itu kunci teragih. Kunci teragih ialah teknologi yang digunakan untuk melindungi akses kepada sumber yang dikongsi. Ia boleh memastikan bahawa berbilang nod tidak akan mengubah suai atau mengakses sumber yang sama pada masa yang sama dalam persekitaran yang diedarkan. Dalam sistem perkhidmatan mikro, kunci yang diedarkan boleh melindungi pembacaan dan penulisan sumber yang dikongsi dan mengelakkan persaingan sumber dan ketidakkonsistenan data.

Seterusnya, kami akan memperkenalkan penyelesaian menggunakan Redis untuk melaksanakan kunci teragih. Redis ialah pangkalan data dalam memori yang popular yang menyokong penguncian teragih dan boleh disepadukan dengan baik dengan rangka kerja Awan Musim Bunga.

Pertama, kita perlu menambah kebergantungan Redis dalam aplikasi Spring Boot. Tambah kebergantungan berikut dalam Gradle:

compile group: 'org.springframework.boot', name: 'spring-boot-starter-data-redis'

Tambah kebergantungan berikut dalam Maven:

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

Tambah kod berikut dalam aplikasi kami untuk mengkonfigurasi sambungan Redis:

@Configuration
public class RedisConfig {

  @Bean
  JedisConnectionFactory jedisConnectionFactory() {
      RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration();
      redisStandaloneConfiguration.setHostName("redis");
      redisStandaloneConfiguration.setPort(6379);
      return new JedisConnectionFactory(redisStandaloneConfiguration);
  }

  @Bean
  public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
      RedisTemplate<String, String> redisTemplate = new RedisTemplate<>();
      redisTemplate.setConnectionFactory(redisConnectionFactory);
      redisTemplate.setDefaultSerializer(new StringRedisSerializer());
      redisTemplate.setEnableTransactionSupport(true);
      redisTemplate.afterPropertiesSet();
      return redisTemplate;
  }
}

Seterusnya, kita perlu melaksanakan kaedah untuk mendapatkan kunci yang diedarkan. Kaedah ini perlu memastikan bahawa hanya satu nod boleh mendapatkan kunci pada masa yang sama dalam persekitaran teragih. Berikut ialah pelaksanaan mudah:

@Service
public class DistributedLockService {

    @Autowired
    private RedisTemplate redisTemplate;

    public boolean acquireLock(String lockKey, String requestId, int expireTime) {

        String result = (String) redisTemplate.execute(new RedisCallback<String>() {
            @Override
            public String doInRedis(RedisConnection connection) throws DataAccessException {
                JedisCommands commands = (JedisCommands) connection.getNativeConnection();
                return commands.set(lockKey, requestId, "NX", "PX", expireTime);
            }
        });

        return result != null && result.equals("OK");
    }

    public boolean releaseLock(String lockKey, String requestId) {
        String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
        Boolean result = (Boolean) redisTemplate.execute(new RedisCallback<Boolean>() {
            @Override
            public Boolean doInRedis(RedisConnection connection) throws DataAccessException {
                Object nativeConnection = connection.getNativeConnection();
                Long execute = (Long) ((Jedis) nativeConnection).eval(script, Collections.singletonList(lockKey), Collections.singletonList(requestId));
                return execute.equals(1L);
            }
        });
        return result;
    }
}

Dalam kod di atas, arahan set Redis dilaksanakan melalui kaedah laksana redisTemplate untuk menetapkan pasangan nilai kunci Parameter NX bermakna ia hanya ditetapkan apabila kunci tidak wujud, mengelakkan keperluan untuk dua Keadaan apabila dua benang memperoleh kunci pada masa yang sama. Parameter PX menunjukkan masa tamat tempoh kunci yang ditetapkan. Hasil pemulangan adalah OK, menunjukkan bahawa kunci berjaya diperoleh. Apabila melepaskan kunci, gunakan pelaksanaan skrip Lua Redis untuk memastikan bahawa hanya benang yang memiliki kunci boleh melepaskan kunci.

Akhir sekali, kita perlu menggunakan kunci teragih dalam perkhidmatan mikro. Sebagai contoh, dengan mengandaikan kami mempunyai titik akhir perkhidmatan mikro yang perlu melindungi akses sumber, kami boleh menggunakan DistributedLockService dalam pengawal Spring MVC untuk mendapatkan kunci teragih bagi memastikan hanya satu permintaan boleh mengakses sumber pada masa yang sama.

@RestController
public class ResourceController {

  private static final String LOCK_KEY = "lock";
  private static final String LOCK_REQUEST_ID = UUID.randomUUID().toString();
  private static final int EXPIRE_TIME = 5000;

  @Autowired
  private DistributedLockService distributedLockService;

  @Autowired
  private ResourceService resourceService;

  @RequestMapping("/resource")
  public ResponseEntity<String> accessResource() {

      boolean lockAcquired = distributedLockService.acquireLock(LOCK_KEY, LOCK_REQUEST_ID, EXPIRE_TIME);

      if (lockAcquired) {
          try {
              // 访问资源
              String result = resourceService.accessResource();
              return ResponseEntity.ok(result);
          } finally {
              distributedLockService.releaseLock(LOCK_KEY, LOCK_REQUEST_ID);
          }
      } else {
          return ResponseEntity.status(HttpStatus.SERVICE_UNAVAILABLE).body("Resource is busy, please try again later.");
      }
  }
}

Kod di atas memperoleh kunci melalui DistributedLockService, mengakses sumber selepas mendapatkan kunci dan melepaskan kunci selepas akses sumber selesai, mengelakkan masalah berbilang permintaan yang mengakses sumber pada masa yang sama.

Dalam contoh di atas, kami melaksanakan skema kunci teragih dalam perkhidmatan mikro Spring Cloud. Penyelesaian ini boleh melindungi akses kepada sumber yang dikongsi dan memastikan ketepatan dan ketekalan data sistem. Dalam penggunaan sebenar, kami boleh melaraskan dan mengoptimumkan pelaksanaan kunci yang diedarkan mengikut senario dan keperluan perniagaan tertentu.

Ringkasnya, kunci teragih adalah bahagian yang sangat penting dalam melaksanakan sistem teragih, yang boleh memastikan ketepatan dan ketekalan data sistem. Gabungan Spring Cloud dan Redis boleh melaksanakan fungsi kunci teragih dengan baik. Melalui pengenalan artikel ini, saya berharap ia dapat memberikan sedikit bantuan untuk semua orang memahami dan menggunakan teknologi kunci teragih.

Atas ialah kandungan terperinci Amalan mikroperkhidmatan Spring Cloud untuk melaksanakan kunci teragih. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn